mirror of
https://github.com/czp3009/bilibili-api.git
synced 2025-02-19 20:50:28 +08:00
stash
This commit is contained in:
parent
1bc0bf61c2
commit
6ed9109b05
@ -6,6 +6,8 @@ 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
|
||||
import com.hiczp.bilibili.api.player.PlayerAPI
|
||||
import com.hiczp.bilibili.api.player.PlayerInterceptor
|
||||
import com.hiczp.bilibili.api.retrofit.Param
|
||||
import com.hiczp.bilibili.api.retrofit.ParamType
|
||||
import com.hiczp.bilibili.api.retrofit.exception.BilibiliApiException
|
||||
@ -86,7 +88,6 @@ class BilibiliClient(
|
||||
)
|
||||
|
||||
private val defaultCommonQueryParamInterceptor = CommonParamInterceptor(ParamType.QUERY, *defaultCommonParamArray)
|
||||
private val defaultSortAndSignInterceptor = SortAndSignInterceptor(billingClientProperties.appSecret)
|
||||
|
||||
/**
|
||||
* 用户鉴权相关的接口
|
||||
@ -102,8 +103,7 @@ class BilibiliClient(
|
||||
"mobi_app" to { billingClientProperties.platform },
|
||||
"platform" to { billingClientProperties.platform },
|
||||
"ts" to { Instant.now().epochSecond.toString() }
|
||||
),
|
||||
defaultSortAndSignInterceptor
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@ -117,8 +117,7 @@ class BilibiliClient(
|
||||
CommonParamInterceptor(ParamType.QUERY, *defaultCommonParamArray,
|
||||
"actionKey" to { "appkey" },
|
||||
"has_up" to { "1" }
|
||||
),
|
||||
defaultSortAndSignInterceptor
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@ -129,8 +128,7 @@ class BilibiliClient(
|
||||
val appAPI by lazy {
|
||||
createAPI<AppAPI>(BaseUrl.app,
|
||||
defaultCommonHeaderInterceptor,
|
||||
defaultCommonQueryParamInterceptor,
|
||||
defaultSortAndSignInterceptor
|
||||
defaultCommonQueryParamInterceptor
|
||||
)
|
||||
}
|
||||
|
||||
@ -147,8 +145,7 @@ class BilibiliClient(
|
||||
"User-Agent" to { "Mozilla/5.0 BiliDroid/5.37.0 (bbcallen@gmail.com)" },
|
||||
"Device-ID" to { billingClientProperties.hardwareId }
|
||||
),
|
||||
defaultCommonQueryParamInterceptor,
|
||||
defaultSortAndSignInterceptor
|
||||
defaultCommonQueryParamInterceptor
|
||||
)
|
||||
}
|
||||
|
||||
@ -166,8 +163,7 @@ class BilibiliClient(
|
||||
"trace_id" to { generateTraceId() },
|
||||
"uid" to { userId?.toString() },
|
||||
"version" to { billingClientProperties.version }
|
||||
),
|
||||
defaultSortAndSignInterceptor
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@ -177,11 +173,31 @@ class BilibiliClient(
|
||||
val memberAPI by lazy {
|
||||
createAPI<MemberAPI>(BaseUrl.member,
|
||||
defaultCommonHeaderInterceptor,
|
||||
defaultCommonQueryParamInterceptor,
|
||||
defaultSortAndSignInterceptor
|
||||
defaultCommonQueryParamInterceptor
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放器所需的 API, 用于获取视频播放地址
|
||||
*/
|
||||
val playerAPI: PlayerAPI by lazy {
|
||||
Retrofit.Builder()
|
||||
.baseUrl("https://bilibili.com") //这里的 baseUrl 是没用的
|
||||
.addConverterFactory(gsonConverterFactory)
|
||||
.addCallAdapterFactory(coroutineCallAdapterFactory)
|
||||
.client(OkHttpClient.Builder().apply {
|
||||
//TODO functional
|
||||
addInterceptor(PlayerInterceptor(billingClientProperties, loginResponse))
|
||||
addInterceptor(FailureResponseInterceptor)
|
||||
//log
|
||||
if (logLevel != HttpLoggingInterceptor.Level.NONE) {
|
||||
addNetworkInterceptor(HttpLoggingInterceptor().setLevel(logLevel))
|
||||
}
|
||||
}.build())
|
||||
.build()
|
||||
.create(PlayerAPI::class.java)
|
||||
}
|
||||
|
||||
/**
|
||||
* 登陆
|
||||
* v3 登陆接口会同时返回 cookies 和 token
|
||||
@ -237,6 +253,7 @@ class BilibiliClient(
|
||||
loginResponse = null
|
||||
}
|
||||
|
||||
private val sortAndSignInterceptor = SortAndSignInterceptor(billingClientProperties.appSecret)
|
||||
private inline fun <reified T : Any> createAPI(
|
||||
baseUrl: String,
|
||||
vararg interceptors: Interceptor
|
||||
@ -248,6 +265,7 @@ class BilibiliClient(
|
||||
interceptors.forEach {
|
||||
addInterceptor(it)
|
||||
}
|
||||
addInterceptor(sortAndSignInterceptor)
|
||||
addInterceptor(FailureResponseInterceptor)
|
||||
//log
|
||||
if (logLevel != HttpLoggingInterceptor.Level.NONE) {
|
||||
|
@ -99,30 +99,4 @@ interface AppAPI {
|
||||
@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>
|
||||
}
|
||||
|
@ -1,78 +0,0 @@
|
||||
package com.hiczp.bilibili.api.app.model
|
||||
|
||||
//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
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
//}
|
@ -31,7 +31,7 @@ data class LoginResponse(
|
||||
) : Serializable {
|
||||
data class Cookie(
|
||||
@SerializedName("expires")
|
||||
var expires: Int, // 1552811689
|
||||
var expires: Long, // 1552811689
|
||||
@SerializedName("http_only")
|
||||
var httpOnly: Int, // 1
|
||||
@SerializedName("name")
|
||||
@ -45,9 +45,9 @@ data class LoginResponse(
|
||||
@SerializedName("access_token")
|
||||
var accessToken: String, // fd0303ff75a6ec6b452c28f4d8621021
|
||||
@SerializedName("expires_in")
|
||||
var expiresIn: Int, // 2592000
|
||||
var expiresIn: Long, // 2592000
|
||||
@SerializedName("mid")
|
||||
var mid: Int, // 20293030
|
||||
var mid: Long, // 20293030
|
||||
@SerializedName("refresh_token")
|
||||
var refreshToken: String // 6a333ebded3c3dbdde65d136b3190d21
|
||||
) : Serializable
|
||||
|
67
src/main/kotlin/com/hiczp/bilibili/api/player/PlayerAPI.kt
Normal file
67
src/main/kotlin/com/hiczp/bilibili/api/player/PlayerAPI.kt
Normal file
@ -0,0 +1,67 @@
|
||||
package com.hiczp.bilibili.api.player
|
||||
|
||||
import com.hiczp.bilibili.api.player.model.BangumiPlayUrl
|
||||
import com.hiczp.bilibili.api.player.model.VideoPlayUrl
|
||||
import kotlinx.coroutines.Deferred
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Query
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* 这里是播放器会访问的 API
|
||||
*/
|
||||
@Suppress("DeferredIsResult", "SpellCheckingInspection")
|
||||
interface PlayerAPI {
|
||||
/**
|
||||
* 获得视频的播放地址
|
||||
* 这个 API 需要使用特别的 appKey
|
||||
*
|
||||
* @param expire 默认为下个月的这一天的时间戳
|
||||
* @param cid 在获取视频详情页面的接口的返回值里
|
||||
* @param aid 视频的唯一标识
|
||||
*
|
||||
* @see com.hiczp.bilibili.api.app.AppAPI.view
|
||||
*/
|
||||
@GET(videoPlayUrl)
|
||||
fun videoPlayUrl(
|
||||
@Query("expire") expire: Long = nextMonthTimestamp(),
|
||||
@Query("force_host") forceHost: Int = 0,
|
||||
@Query("fnval") fnVal: Int = 16,
|
||||
@Query("qn") qn: Int = 32,
|
||||
@Query("npcybs") npcybs: Int = 0,
|
||||
@Query("cid") cid: Long,
|
||||
@Query("otype") otype: String = "json",
|
||||
@Query("fnver") fnVer: Int = 0,
|
||||
@Query("aid") aid: Long
|
||||
): Deferred<VideoPlayUrl>
|
||||
|
||||
/**
|
||||
* 获得番剧的播放地址
|
||||
*
|
||||
* @param aid 番剧的唯一标识
|
||||
* @param cid 在番剧详情页的返回值里
|
||||
* @param seasonType 番剧分季(第一季, 第二季)(从 1 开始)
|
||||
* @param session 不明确其含义
|
||||
* @param trackPath 不明确
|
||||
*/
|
||||
@GET("https://api.bilibili.com/pgc/player/api/playurl")
|
||||
fun bangumiPlayUrl(
|
||||
@Query("aid") aid: Long,
|
||||
@Query("cid") cid: Long,
|
||||
@Query("expire") expire: Long = nextMonthTimestamp(),
|
||||
@Query("fnval") fnVal: Int = 16,
|
||||
@Query("fnver") fnVer: Int = 0,
|
||||
@Query("module") module: String = "bangumi",
|
||||
@Query("npcybs") npcybs: Int = 0,
|
||||
@Query("otype") otype: String = "json",
|
||||
@Query("qn") qn: Int = 32,
|
||||
@Query("season_type") seasonType: Int,
|
||||
@Query("session") session: String? = null,
|
||||
@Query("track_path") trackPath: Int? = null
|
||||
): Deferred<BangumiPlayUrl>
|
||||
|
||||
companion object {
|
||||
const val videoPlayUrl = "https://app.bilibili.com/x/playurl"
|
||||
private fun nextMonthTimestamp() = Calendar.getInstance().apply { add(Calendar.MONTH, 1) }.toInstant().epochSecond
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.hiczp.bilibili.api.player
|
||||
|
||||
import com.hiczp.bilibili.api.BilibiliClientProperties
|
||||
import com.hiczp.bilibili.api.passport.model.LoginResponse
|
||||
import com.hiczp.bilibili.api.retrofit.Header
|
||||
import com.hiczp.bilibili.api.retrofit.Param
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import java.time.Instant
|
||||
|
||||
/**
|
||||
* PlayerAPI 专用的拦截器
|
||||
*
|
||||
* @see PlayerAPI
|
||||
*/
|
||||
class PlayerInterceptor(
|
||||
private val bilibiliClientProperties: BilibiliClientProperties,
|
||||
private val loginResponse: LoginResponse?
|
||||
) : Interceptor {
|
||||
@Suppress("SpellCheckingInspection")
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val request = chain.request()
|
||||
|
||||
val header = request.headers().newBuilder().apply {
|
||||
add("Accept", "*/*")
|
||||
add("User-Agent", "Bilibili Freedoooooom/MarkII")
|
||||
add("Accept-Language", Header.ZH_CN)
|
||||
}.build()
|
||||
|
||||
val url = request.url().newBuilder().apply {
|
||||
//视频播放地址(非番剧)这个接口要用 videoAppKey
|
||||
if (request.url().toString().startsWith(PlayerAPI.videoPlayUrl)) {
|
||||
addQueryParameter(Param.APP_KEY, bilibiliClientProperties.videoAppKey)
|
||||
} else {
|
||||
addQueryParameter(Param.APP_KEY, bilibiliClientProperties.appKey)
|
||||
}
|
||||
//公共参数
|
||||
addQueryParameter("device", bilibiliClientProperties.platform)
|
||||
addQueryParameter("mobi_app", bilibiliClientProperties.platform)
|
||||
if (loginResponse != null) {
|
||||
addQueryParameter("mid", loginResponse.userId.toString())
|
||||
addQueryParameter(Param.ACCESS_KEY, loginResponse.token)
|
||||
}
|
||||
addQueryParameter("platform", bilibiliClientProperties.platform)
|
||||
addQueryParameter("ts", Instant.now().epochSecond.toString())
|
||||
addQueryParameter("build", bilibiliClientProperties.build)
|
||||
addQueryParameter("buvid", bilibiliClientProperties.buildVersionId)
|
||||
}.build()
|
||||
|
||||
return chain.proceed(
|
||||
request.newBuilder()
|
||||
.headers(header)
|
||||
.url(url)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.hiczp.bilibili.api.player.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class BangumiPlayUrl(
|
||||
@SerializedName("accept_description")
|
||||
var acceptDescription: List<String>,
|
||||
@SerializedName("accept_format")
|
||||
var acceptFormat: String, // hdflv2,flv,flv720,flv480,mp4
|
||||
@SerializedName("accept_quality")
|
||||
var acceptQuality: List<Int>,
|
||||
@SerializedName("bp")
|
||||
var bp: Int, // 0
|
||||
@SerializedName("code")
|
||||
var code: Int, // 0
|
||||
@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("has_paid")
|
||||
var hasPaid: Boolean, // false
|
||||
@SerializedName("is_preview")
|
||||
var isPreview: Int, // 0
|
||||
@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("status")
|
||||
var status: Int, // 2
|
||||
@SerializedName("timelength")
|
||||
var timelength: Int, // 1420201
|
||||
@SerializedName("video_codecid")
|
||||
var videoCodecid: Int, // 7
|
||||
@SerializedName("video_project")
|
||||
var videoProject: Boolean, // true
|
||||
@SerializedName("vip_status")
|
||||
var vipStatus: Int, // 0
|
||||
@SerializedName("vip_type")
|
||||
var vipType: Int // 0
|
||||
) {
|
||||
data class Dash(
|
||||
@SerializedName("audio")
|
||||
var audio: List<Audio>,
|
||||
@SerializedName("video")
|
||||
var video: List<Video>
|
||||
) {
|
||||
data class Video(
|
||||
@SerializedName("backupUrl")
|
||||
var backupUrl: List<String>,
|
||||
@SerializedName("backup_url")
|
||||
var backup_url: List<String>,
|
||||
@SerializedName("bandwidth")
|
||||
var bandwidth: Int, // 379067
|
||||
@SerializedName("baseUrl")
|
||||
var baseUrl: String, // http://60.12.119.70/upgcxcode/28/12/74921228/74921228-1-30016.m4s?expires=1550754300&platform=android&ssig=rJUT9lWneFYshCT4p_3YuA&oi=1699214834&trid=83334c4981ed460ea2444f6aab79d1b6&nfb=maPYqpoel5MI3qOUX6YpRA==&nfc=1
|
||||
@SerializedName("base_url")
|
||||
var base_url: String, // http://60.12.119.70/upgcxcode/28/12/74921228/74921228-1-30016.m4s?expires=1550754300&platform=android&ssig=rJUT9lWneFYshCT4p_3YuA&oi=1699214834&trid=83334c4981ed460ea2444f6aab79d1b6&nfb=maPYqpoel5MI3qOUX6YpRA==&nfc=1
|
||||
@SerializedName("codecid")
|
||||
var codecid: Int, // 7
|
||||
@SerializedName("id")
|
||||
var id: Int // 16
|
||||
)
|
||||
|
||||
data class Audio(
|
||||
@SerializedName("backupUrl")
|
||||
var backupUrl: List<String>,
|
||||
@SerializedName("backup_url")
|
||||
var backup_url: List<String>,
|
||||
@SerializedName("bandwidth")
|
||||
var bandwidth: Int, // 193680
|
||||
@SerializedName("baseUrl")
|
||||
var baseUrl: String, // http://60.12.119.68/upgcxcode/28/12/74921228/74921228-1-30280.m4s?expires=1550754300&platform=android&ssig=1-JiBSZvopajZNgVZ3HRdA&oi=1699214834&trid=83334c4981ed460ea2444f6aab79d1b6&nfb=maPYqpoel5MI3qOUX6YpRA==&nfc=1
|
||||
@SerializedName("base_url")
|
||||
var base_url: String, // http://60.12.119.68/upgcxcode/28/12/74921228/74921228-1-30280.m4s?expires=1550754300&platform=android&ssig=1-JiBSZvopajZNgVZ3HRdA&oi=1699214834&trid=83334c4981ed460ea2444f6aab79d1b6&nfb=maPYqpoel5MI3qOUX6YpRA==&nfc=1
|
||||
@SerializedName("id")
|
||||
var id: Int // 30280
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package com.hiczp.bilibili.api.player.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class VideoPlayUrl(
|
||||
@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, // flv_p60,flv720_p60,flv,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, // 196367
|
||||
@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 Audio(
|
||||
@SerializedName("backup_url")
|
||||
var backupUrl: List<String>,
|
||||
@SerializedName("bandwidth")
|
||||
var bandwidth: Int, // 191246
|
||||
@SerializedName("base_url")
|
||||
var baseUrl: String, // http://101.75.242.10/upgcxcode/41/36/72913641/72913641-1-30280.m4s?expires=1550754000&platform=android&ssig=2eirz02lIhKUw--w26lpqQ&oi=1699214834&trid=e0d3ad6245d8432887eb12b71f29bb3e&nfb=maPYqpoel5MI3qOUX6YpRA==&nfc=1
|
||||
@SerializedName("codecid")
|
||||
var codecid: Int, // 0
|
||||
@SerializedName("id")
|
||||
var id: Int // 30280
|
||||
)
|
||||
|
||||
data class Video(
|
||||
@SerializedName("backup_url")
|
||||
var backupUrl: List<String>,
|
||||
@SerializedName("bandwidth")
|
||||
var bandwidth: Int, // 288340
|
||||
@SerializedName("base_url")
|
||||
var baseUrl: String, // http://60.12.119.68/upgcxcode/41/36/72913641/72913641-1-30011.m4s?expires=1550754000&platform=android&ssig=Ven-c2XaxfkQIoMkzuq7MQ&oi=1699214834&trid=e0d3ad6245d8432887eb12b71f29bb3e&nfb=maPYqpoel5MI3qOUX6YpRA==&nfc=1
|
||||
@SerializedName("codecid")
|
||||
var codecid: Int, // 12
|
||||
@SerializedName("id")
|
||||
var id: Int // 16
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -11,9 +11,10 @@ object Method {
|
||||
const val OPTION = "OPTION"
|
||||
}
|
||||
|
||||
object ContentType {
|
||||
object Header {
|
||||
const val JSON = "application/json"
|
||||
const val FORM_URLENCODED = "application/x-www-form-urlencoded; charset=utf-8"
|
||||
const val ZH_CN = "zh-CN,zh;q=0.8"
|
||||
}
|
||||
|
||||
object Param {
|
||||
|
@ -19,9 +19,13 @@ object Config {
|
||||
|
||||
val password by config.byString
|
||||
|
||||
val presetBilibiliClient by lazy {
|
||||
//登陆过的实例
|
||||
val bilibiliClient by lazy {
|
||||
BilibiliClient(logLevel = HttpLoggingInterceptor.Level.BODY).apply {
|
||||
loginResponse = config["loginResponse"]?.let { gson.fromJson(it) }
|
||||
}
|
||||
}
|
||||
|
||||
//未登录的实例
|
||||
val noLoginBilibiliClient = BilibiliClient(logLevel = HttpLoggingInterceptor.Level.BODY)
|
||||
}
|
||||
|
@ -1,24 +1,20 @@
|
||||
package com.hiczp.bilibili.api.test
|
||||
|
||||
import com.hiczp.bilibili.api.BilibiliClient
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class FetchReplyTest {
|
||||
@Test
|
||||
fun fetchReply() {
|
||||
runBlocking {
|
||||
BilibiliClient(logLevel = HttpLoggingInterceptor.Level.BODY)
|
||||
.mainAPI.reply(oid = 44154463).await()
|
||||
Config.noLoginBilibiliClient.mainAPI.reply(oid = 44154463).await()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchChildReply() {
|
||||
runBlocking {
|
||||
BilibiliClient(logLevel = HttpLoggingInterceptor.Level.BODY)
|
||||
.mainAPI.childReply(oid = 16622855, root = 1405602348).await()
|
||||
Config.noLoginBilibiliClient.mainAPI.childReply(oid = 16622855, root = 1405602348).await()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
24
src/test/kotlin/com/hiczp/bilibili/api/test/PlayUrlTest.kt
Normal file
24
src/test/kotlin/com/hiczp/bilibili/api/test/PlayUrlTest.kt
Normal file
@ -0,0 +1,24 @@
|
||||
package com.hiczp.bilibili.api.test
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class PlayUrlTest {
|
||||
@Test
|
||||
fun videoPlayUrl() {
|
||||
runBlocking {
|
||||
Config.noLoginBilibiliClient.playerAPI.run {
|
||||
videoPlayUrl(aid = 41517911, cid = 72913641).await()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun bangumiPlayUrl() {
|
||||
runBlocking {
|
||||
Config.noLoginBilibiliClient.playerAPI.run {
|
||||
bangumiPlayUrl(aid = 42714241, cid = 74921228, seasonType = 1).await()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ class UserInfoTest {
|
||||
@Test
|
||||
fun info() {
|
||||
runBlocking {
|
||||
Config.presetBilibiliClient.appAPI.myInfo().await()
|
||||
Config.bilibiliClient.appAPI.myInfo().await()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user