✨ feat(im): 基于 livekit 构建 im 通话(语音聊天、视频聊天、共享桌面)v0.1:推进中
parent
e12596ad7c
commit
750f25410c
|
|
@ -56,6 +56,7 @@
|
||||||
"jsbarcode": "^3.12.3",
|
"jsbarcode": "^3.12.3",
|
||||||
"jsencrypt": "^3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
"jsoneditor": "^10.1.3",
|
"jsoneditor": "^10.1.3",
|
||||||
|
"livekit-client": "^2.18.9",
|
||||||
"localforage": "^1.10.0",
|
"localforage": "^1.10.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,162 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
/** 会话场景;对齐后端 ImConversationTypeEnum */
|
||||||
|
export const ImCallScene = {
|
||||||
|
PRIVATE: 1,
|
||||||
|
GROUP: 2
|
||||||
|
} as const
|
||||||
|
|
||||||
|
/** 媒体类型;对齐后端 ImCallMediaTypeEnum */
|
||||||
|
export const ImCallMediaType = {
|
||||||
|
VOICE: 1,
|
||||||
|
VIDEO: 2
|
||||||
|
} as const
|
||||||
|
|
||||||
|
/** 通话状态;对齐后端 ImCallStatusEnum */
|
||||||
|
export const ImCallStatus = {
|
||||||
|
INVITING: 10,
|
||||||
|
ONGOING: 20,
|
||||||
|
ENDED: 30
|
||||||
|
} as const
|
||||||
|
|
||||||
|
/** 通话结束原因;对齐后端 ImCallEndReasonEnum */
|
||||||
|
export const ImCallEndReason = {
|
||||||
|
HANGUP: 1,
|
||||||
|
REJECT: 2,
|
||||||
|
CANCEL: 3,
|
||||||
|
TIMEOUT: 4,
|
||||||
|
BUSY: 5,
|
||||||
|
ERROR: 9
|
||||||
|
} as const
|
||||||
|
|
||||||
|
/** 发起通话请求 VO */
|
||||||
|
export interface ImRtcCallInviteReqVO {
|
||||||
|
scene: number
|
||||||
|
mediaType: number
|
||||||
|
peerUserId?: number
|
||||||
|
groupId?: number
|
||||||
|
/** 群通话场景:前端选定的子集;为空回退到群活跃成员 */
|
||||||
|
inviteeIds?: number[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 通话中添加成员请求 VO */
|
||||||
|
export interface ImRtcCallInviteMoreReqVO {
|
||||||
|
roomName: string
|
||||||
|
inviteeIds: number[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 通话会话 VO;invite / accept / refreshToken / getActiveSessions 共用 */
|
||||||
|
export interface ImRtcCallRespVO {
|
||||||
|
callId: string
|
||||||
|
roomName: string
|
||||||
|
livekitUrl: string
|
||||||
|
token?: string
|
||||||
|
scene: number
|
||||||
|
mediaType: number
|
||||||
|
status: number
|
||||||
|
inviterId: number
|
||||||
|
groupId?: number
|
||||||
|
inviteeIds?: number[]
|
||||||
|
joinedUserIds?: number[]
|
||||||
|
newCreated?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/** RTC_INVITE 信令载荷;payload 走 ImPrivateMessageDTO.content(JSON 字符串) */
|
||||||
|
export interface ImRtcInviteNotification {
|
||||||
|
callId: string
|
||||||
|
roomName: string
|
||||||
|
livekitUrl: string
|
||||||
|
token: string
|
||||||
|
scene: number
|
||||||
|
mediaType: number
|
||||||
|
inviterId: number
|
||||||
|
inviterNickname?: string
|
||||||
|
inviterAvatar?: string
|
||||||
|
groupId?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/** RTC_ACCEPT 信令载荷 */
|
||||||
|
export interface ImRtcAcceptNotification {
|
||||||
|
callId: string
|
||||||
|
roomName: string
|
||||||
|
acceptorId: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/** RTC_END 信令载荷 */
|
||||||
|
export interface ImRtcEndNotification {
|
||||||
|
callId: string
|
||||||
|
roomName: string
|
||||||
|
operatorId?: number
|
||||||
|
reason: number
|
||||||
|
durationSeconds?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/** RTC_GROUP_STARTED / RTC_GROUP_UPDATED / RTC_GROUP_ENDED 共用载荷 */
|
||||||
|
export interface ImRtcGroupNotification {
|
||||||
|
callId: string
|
||||||
|
roomName: string
|
||||||
|
groupId: number
|
||||||
|
mediaType: number
|
||||||
|
inviterId: number
|
||||||
|
joinedUserIds?: number[]
|
||||||
|
inviteeIds?: number[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 群活跃通话查询响应;不含 token */
|
||||||
|
export interface ImRtcGroupCallRespVO {
|
||||||
|
callId: string
|
||||||
|
roomName: string
|
||||||
|
groupId: number
|
||||||
|
mediaType: number
|
||||||
|
inviterId: number
|
||||||
|
joinedUserIds?: number[]
|
||||||
|
inviteeIds?: number[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 发起通话;同好友对 / 群已有进行中通话则返回该会话并标记 newCreated=false */
|
||||||
|
export const inviteCall = (data: ImRtcCallInviteReqVO) => {
|
||||||
|
return request.post<ImRtcCallRespVO>({ url: '/im/rtc/invite', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 通话中添加成员;仅群通话可用 */
|
||||||
|
export const inviteMoreCall = (data: ImRtcCallInviteMoreReqVO) => {
|
||||||
|
return request.post<boolean>({ url: '/im/rtc/invite-more', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 接听通话 */
|
||||||
|
export const acceptCall = (roomName: string) => {
|
||||||
|
return request.post<ImRtcCallRespVO>({ url: '/im/rtc/accept', params: { roomName } })
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 拒绝通话 */
|
||||||
|
export const rejectCall = (roomName: string) => {
|
||||||
|
return request.post<boolean>({ url: '/im/rtc/reject', params: { roomName } })
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 取消邀请;主叫接通前调用 */
|
||||||
|
export const cancelCall = (roomName: string) => {
|
||||||
|
return request.post<boolean>({ url: '/im/rtc/cancel', params: { roomName } })
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 离开通话;接通后调用 */
|
||||||
|
export const leaveCall = (roomName: string) => {
|
||||||
|
return request.post<boolean>({ url: '/im/rtc/leave', params: { roomName } })
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重新签发 Token;客户端重连或 Token 过期续期 */
|
||||||
|
export const refreshCallToken = (roomName: string) => {
|
||||||
|
return request.get<ImRtcCallRespVO>({ url: '/im/rtc/refresh-token', params: { roomName } })
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询当前用户活跃通话;冷启动 / 推送点开恢复 */
|
||||||
|
export const getActiveCallSessions = () => {
|
||||||
|
return request.get<ImRtcCallRespVO[]>({ url: '/im/rtc/active-sessions' })
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询群当前进行中的通话;用于群聊顶部胶囊条;返回 null 表示无活跃通话 */
|
||||||
|
export const getGroupActiveCall = (groupId: number) => {
|
||||||
|
return request.get<ImRtcGroupCallRespVO | null>({
|
||||||
|
url: '/im/rtc/group-active-call',
|
||||||
|
params: { groupId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,15 @@ export const ImMessageType = {
|
||||||
RECALL: 2101, // 撤回(对应 OpenIM RevokeNotification=2101)
|
RECALL: 2101, // 撤回(对应 OpenIM RevokeNotification=2101)
|
||||||
RECEIPT: 2200, // 回执(对应 OpenIM HasReadReceipt=2200)
|
RECEIPT: 2200, // 回执(对应 OpenIM HasReadReceipt=2200)
|
||||||
READ: 2201, // 已读(多端同步,OpenIM 无对应;自有扩展)
|
READ: 2201, // 已读(多端同步,OpenIM 无对应;自有扩展)
|
||||||
|
// TODO @AI:是不是要把单聊、群聊的信令融合?
|
||||||
|
// ========== 实时通话信令(2300-2302) ==========
|
||||||
|
RTC_INVITE: 2300, // 通话邀请(推给被叫弹来电)
|
||||||
|
RTC_ACCEPT: 2301, // 通话接通(推给主叫切到通话中 UI)
|
||||||
|
RTC_END: 2302, // 通话结束(拒绝/取消/挂断/超时统一)
|
||||||
|
// ========== 群通话广播(2310-2312):让所有群成员能看胶囊条 / 主动加入 ==========
|
||||||
|
RTC_GROUP_STARTED: 2310, // 群通话开始(全群广播)
|
||||||
|
RTC_GROUP_ENDED: 2311, // 群通话结束(全群广播;胶囊条移除)
|
||||||
|
RTC_GROUP_UPDATED: 2312, // 群通话成员变更(全群广播;胶囊条人数刷新)
|
||||||
// ========== 好友通知(1201-1210 直接复用 OpenIM 段位编号) ==========
|
// ========== 好友通知(1201-1210 直接复用 OpenIM 段位编号) ==========
|
||||||
FRIEND_REQUEST_APPROVED: 1201, // 好友申请被同意
|
FRIEND_REQUEST_APPROVED: 1201, // 好友申请被同意
|
||||||
FRIEND_REQUEST_REJECTED: 1202, // 好友申请被拒绝
|
FRIEND_REQUEST_REJECTED: 1202, // 好友申请被拒绝
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue