直播站 API 开工

This commit is contained in:
czp3009 2019-03-12 18:39:00 +08:00
parent 17af93619d
commit dce45203c9
9 changed files with 468 additions and 2 deletions

View File

@ -2,6 +2,7 @@ package com.hiczp.bilibili.api
import com.hiczp.bilibili.api.app.AppAPI
import com.hiczp.bilibili.api.danmaku.DanmakuAPI
import com.hiczp.bilibili.api.live.LiveAPI
import com.hiczp.bilibili.api.main.MainAPI
import com.hiczp.bilibili.api.member.MemberAPI
import com.hiczp.bilibili.api.message.MessageAPI
@ -217,6 +218,25 @@ class BilibiliClient(
.create(DanmakuAPI::class.java)
}
/**
* 直播站
*/
val liveAPI by lazy {
createAPI<LiveAPI>(BaseUrl.live,
CommonHeaderInterceptor(
//如果未登陆则没有 Display-ID
Header.DISPLAY_ID to { userId?.let { "$it-$initTime" } },
Header.BUILD_VERSION_ID to { billingClientProperties.buildVersionId },
Header.USER_AGENT to { billingClientProperties.defaultUserAgent },
Header.DEVICE_ID to { billingClientProperties.hardwareId }
),
CommonParamInterceptor(*defaultCommonParamArray,
Param.ACTION_KEY to { Param.APP_KEY },
Param.DEVICE to { billingClientProperties.platform }
)
)
}
/**
* 登陆
* v3 登陆接口会同时返回 cookies token

View File

@ -0,0 +1,67 @@
package com.hiczp.bilibili.api.live
import com.hiczp.bilibili.api.live.model.*
import com.hiczp.bilibili.api.retrofit.CommonResponse
import kotlinx.coroutines.Deferred
import retrofit2.http.*
/**
* 直播站 API
*/
@Suppress("DeferredIsResult")
interface LiveAPI {
/**
* 获取一个房间的基本信息
*
* @param id 房间号或房间短号
*/
@GET("/room/v1/Room/mobileRoomInit")
fun mobileRoomInit(@Query("id") id: Long): Deferred<MobileRoom>
/**
* 进入房间时客户端将访问该接口
* 访问该接口将在自己的账户中产生一条观看直播的历史记录
*
* @param roomId 房间号(没试过能不能用短号, 下同)
*/
@POST("/room/v1/Room/room_entry_action")
@FormUrlEncoded
fun roomEntryAction(
@Field("room_id") roomId: Long,
@Field("jumpFrom") jumpFrom: Int? = 0
): Deferred<CommonResponse>
/**
* 获取一个房间的详细信息
*
* @param id 房间号
*/
@GET("/room/v1/Room/get_info")
fun getInfo(@Query("id") id: Long): Deferred<RoomInfo>
/**
* 获取弹幕服务器
*
* @param roomId 房间号
*/
@GET("/room/v1/Danmu/getConf")
fun getDanmakuConfig(
@Field("room_id") roomId: Long
): Deferred<DanmakuConfig>
/**
* 获取该房间的主播的头像和等级一类的信息
*
* @param roomId 房间号
*/
@Suppress("SpellCheckingInspection")
@GET("/live_user/v1/UserInfo/get_anchor_in_room")
fun getAnchorInRoom(@Query("roomid") roomId: Long): Deferred<AnchorInRoom>
/**
* 获取自己在直播间的基本信息, 包括自己的直播间号, 银瓜子, 金瓜子数量等
*/
@GET("/mobile/getUser")
fun getUser(): Deferred<User>
}

View File

@ -0,0 +1,103 @@
package com.hiczp.bilibili.api.live.model
import com.google.gson.annotations.SerializedName
data class AnchorInRoom(
@SerializedName("code")
var code: Int, // 0
@SerializedName("data")
var `data`: Data,
@SerializedName("message")
var message: String, // success
@SerializedName("msg")
var msg: String // success
) {
data class Data(
@SerializedName("info")
var info: Info,
@SerializedName("level")
var level: Level,
@SerializedName("san")
var san: String // 12
) {
data class Info(
@SerializedName("face")
var face: String, // https://i1.hdslb.com/bfs/face/4f65e79399ad5a1bf3f877851b2f819d5870b494.jpg
@SerializedName("gender")
var gender: Int, // 0
@SerializedName("identification")
var identification: Int, // 1
@SerializedName("mobile_verify")
var mobileVerify: Int, // 1
@SerializedName("official_verify")
var officialVerify: OfficialVerify,
@SerializedName("platform_user_level")
var platformUserLevel: Int, // 4
@SerializedName("rank")
var rank: String, // 10000
@SerializedName("uid")
var uid: Long, // 20293030
@SerializedName("uname")
var uname: String, // czp3009
@SerializedName("vip_type")
var vipType: Int // 0
) {
data class OfficialVerify(
@SerializedName("desc")
var desc: String,
@SerializedName("role")
var role: Int, // 0
@SerializedName("type")
var type: Int // -1
)
}
data class Level(
@SerializedName("anchor_score")
var anchorScore: Int, // 27376
@SerializedName("color")
var color: Int, // 5805790
@SerializedName("cost")
var cost: Int, // 52187800
@SerializedName("master_level")
var masterLevel: MasterLevel,
@SerializedName("rcost")
var rcost: Int, // 2737665
@SerializedName("svip")
var svip: Int, // 0
@SerializedName("svip_time")
var svipTime: String, // 0000-00-00 00:00:00
@SerializedName("uid")
var uid: Int, // 20293030
@SerializedName("update_time")
var updateTime: String, // 2019-03-12 16:00:48
@SerializedName("user_level")
var userLevel: Int, // 25
@SerializedName("user_score")
var userScore: String, // 0
@SerializedName("vip")
var vip: Int, // 0
@SerializedName("vip_time")
var vipTime: String // 2018-05-15 12:00:50
) {
data class MasterLevel(
@SerializedName("anchor_score")
var anchorScore: Int, // 27376
@SerializedName("color")
var color: Int, // 5805790
@SerializedName("current")
var current: List<Int>,
@SerializedName("level")
var level: Int, // 11
@SerializedName("master_level_color")
var masterLevelColor: Int, // 5805790
@SerializedName("next")
var next: List<Int>,
@SerializedName("sort")
var sort: String, // >10000
@SerializedName("upgrade_score")
var upgradeScore: Int // 12234
)
}
}
}

View File

@ -0,0 +1,49 @@
package com.hiczp.bilibili.api.live.model
import com.google.gson.annotations.SerializedName
data class DanmakuConfig(
@SerializedName("code")
var code: Int, // 0
@SerializedName("data")
var `data`: Data,
@SerializedName("message")
var message: String, // ok
@SerializedName("msg")
var msg: String // ok
) {
data class Data(
@SerializedName("host")
var host: String, // broadcastlv.chat.bilibili.com
@SerializedName("host_server_list")
var hostServerList: List<HostServer>,
@SerializedName("max_delay")
var maxDelay: Int, // 5000
@SerializedName("port")
var port: Int, // 2243
@SerializedName("refresh_rate")
var refreshRate: Int, // 100
@SerializedName("refresh_row_factor")
var refreshRowFactor: Double, // 0.125
@SerializedName("server_list")
var serverList: List<Server>
) {
data class Server(
@SerializedName("host")
var host: String, // broadcastlv.chat.bilibili.com
@SerializedName("port")
var port: Int // 80
)
data class HostServer(
@SerializedName("host")
var host: String, // broadcastlv.chat.bilibili.com
@SerializedName("port")
var port: Int, // 2243
@SerializedName("ws_port")
var wsPort: Int, // 2244
@SerializedName("wss_port")
var wssPort: Int // 443
)
}
}

View File

@ -0,0 +1,58 @@
package com.hiczp.bilibili.api.live.model
import com.google.gson.annotations.SerializedName
data class MobileRoom(
@SerializedName("code")
var code: Int, // 0
@SerializedName("data")
var `data`: Data,
@SerializedName("message")
var message: String, // ok
@SerializedName("msg")
var msg: String // ok
) {
data class Data(
@SerializedName("encrypted")
var encrypted: Boolean, // false
@SerializedName("hidden_till")
var hiddenTill: Int, // 0
@SerializedName("is_hidden")
var isHidden: Boolean, // false
@SerializedName("is_locked")
var isLocked: Boolean, // false
@SerializedName("is_portrait")
var isPortrait: Boolean, // false
@SerializedName("is_sp")
var isSp: Int, // 0
@SerializedName("live_status")
var liveStatus: Int, // 0
@SerializedName("live_time")
var liveTime: Long, // -62170012800
@SerializedName("lock_till")
var lockTill: Int, // 0
@SerializedName("need_p2p")
var needP2p: Int, // 0
@SerializedName("pwd_verified")
var pwdVerified: Boolean, // true
/**
* 实际房间号
*/
@SerializedName("room_id")
var roomId: Long, // 1110317
/**
* 如果房间有短号则 roomShield 1
*/
@SerializedName("room_shield")
var roomShield: Int, // 0
/**
* 短房间号
*/
@SerializedName("short_id")
var shortId: Int, // 0
@SerializedName("special_type")
var specialType: Int, // 0
@SerializedName("uid")
var uid: Long // 20293030
)
}

View File

@ -0,0 +1,99 @@
package com.hiczp.bilibili.api.live.model
import com.google.gson.JsonElement
import com.google.gson.annotations.SerializedName
data class RoomInfo(
@SerializedName("code")
var code: Int, // 0
@SerializedName("data")
var `data`: Data,
@SerializedName("message")
var message: String, // ok
@SerializedName("msg")
var msg: String // ok
) {
data class Data(
@SerializedName("allow_change_area_time")
var allowChangeAreaTime: Int, // 0
@SerializedName("allow_upload_cover_time")
var allowUploadCoverTime: Int, // 0
@SerializedName("area_id")
var areaId: Int, // 107
@SerializedName("area_name")
var areaName: String, // 其他游戏
@SerializedName("area_pendants")
var areaPendants: String,
@SerializedName("attention")
var attention: Int, // 62
@SerializedName("background")
var background: String,
@SerializedName("description")
var description: String, // <p>立即安装Jetbrains, 享受精彩人生!</p>
@SerializedName("hot_words")
var hotWords: List<String>,
@SerializedName("hot_words_status")
var hotWordsStatus: Int, // 0
@SerializedName("is_anchor")
var isAnchor: Int, // 1
@SerializedName("is_portrait")
var isPortrait: Boolean, // false
@SerializedName("is_strict_room")
var isStrictRoom: Boolean, // false
@SerializedName("keyframe")
var keyframe: String, // https://i0.hdslb.com/bfs/live/1110317.jpg?03092037
@SerializedName("live_status")
var liveStatus: Int, // 0
@SerializedName("live_time")
var liveTime: String, // 0000-00-00 00:00:00
@SerializedName("new_pendants")
var newPendants: NewPendants,
@SerializedName("old_area_id")
var oldAreaId: Int, // 1
@SerializedName("online")
var online: Int, // 18
@SerializedName("parent_area_id")
var parentAreaId: Int, // 2
@SerializedName("parent_area_name")
var parentAreaName: String, // 网游
@SerializedName("pendants")
var pendants: String,
@SerializedName("pk_id")
var pkId: Int, // 0
@SerializedName("pk_status")
var pkStatus: Int, // 0
@SerializedName("room_id")
var roomId: Long, // 1110317
@SerializedName("room_silent_level")
var roomSilentLevel: Int, // 0
@SerializedName("room_silent_second")
var roomSilentSecond: Int, // 0
@SerializedName("room_silent_type")
var roomSilentType: String,
@SerializedName("short_id")
var shortId: Int, // 0
@SerializedName("tags")
var tags: String, // 编程
@SerializedName("title")
var title: String, // 太空程序员
@SerializedName("uid")
var uid: Long, // 20293030
@SerializedName("up_session")
var upSession: String,
@SerializedName("user_cover")
var userCover: String, // https://i0.hdslb.com/bfs/live/b4d4dbf35f7a30fb6b0a2ea4077514235262797e.jpg
@SerializedName("verify")
var verify: String
) {
data class NewPendants(
@SerializedName("badge")
var badge: JsonElement?, // null
@SerializedName("frame")
var frame: JsonElement?, // null
@SerializedName("mobile_badge")
var mobileBadge: JsonElement?, // null
@SerializedName("mobile_frame")
var mobileFrame: JsonElement? // null
)
}
}

View File

@ -0,0 +1,54 @@
package com.hiczp.bilibili.api.live.model
import com.google.gson.annotations.SerializedName
data class User(
@SerializedName("code")
var code: Int, // 0
@SerializedName("data")
var `data`: Data,
@SerializedName("message")
var message: String, // OK
@SerializedName("msg")
var msg: String // OK
) {
data class Data(
@SerializedName("gold")
var gold: Int, // 0
@SerializedName("isSign")
var isSign: Int, // 0
@SerializedName("medal")
var medal: Any?, // null
@SerializedName("new")
var new: Int, // 1
@SerializedName("room_id")
var roomId: Long, // 1110317
@SerializedName("silver")
var silver: Int, // 140258
@SerializedName("svip")
var svip: Int, // 0
@SerializedName("svip_time")
var svipTime: String, // 0000-00-00 00:00:00
@SerializedName("use_count")
var useCount: Int, // 0
@SerializedName("user_level")
var userLevel: Int, // 25
@SerializedName("user_level_color")
var userLevelColor: Int, // 5805790
@SerializedName("vip")
var vip: Int, // 0
@SerializedName("vip_time")
var vipTime: String, // 2018-05-15 12:00:50
@SerializedName("vip_view_status")
var vipViewStatus: Int, // 1
@SerializedName("wearTitle")
var wearTitle: WearTitle
) {
data class WearTitle(
@SerializedName("activity")
var activity: String, // 0
@SerializedName("title")
var title: String // 0
)
}
}

View File

@ -24,9 +24,10 @@ object Header {
//强制公共参数添加位置
const val FORCE_PARAM = "Retrofit-Force-Param"
const val FORCE_PARAM_QUERY = "query"
const val FORCE_PARAM_FORMBODY = "formBody"
@Suppress("MemberVisibilityCanBePrivate")
const val FORCE_PARAM_FORM_BODY = "formBody"
const val FORCE_QUERY = "$FORCE_PARAM: $FORCE_PARAM_QUERY"
const val FORCE_FORMBODY = "$FORCE_PARAM: $FORCE_PARAM_FORMBODY"
const val FORCE_FORM_BODY = "$FORCE_PARAM: $FORCE_PARAM_FORM_BODY"
}
object Param {

View File

@ -0,0 +1,15 @@
package com.hiczp.bilibili.api.test
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Test
class EnterRoomTest {
@Test
fun enterRoom() {
runBlocking {
val roomId = bilibiliClient.liveAPI.mobileRoomInit(3).await().data.roomId
bilibiliClient.liveAPI.roomEntryAction(roomId).await()
bilibiliClient.liveAPI.getInfo(roomId).await()
}
}
}