Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
pidan
/
FuSiLive
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
00aee5e3
authored
Mar 06, 2026
by
suolong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
个人通话bug
parent
c0758565
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
176 additions
and
119 deletions
Modules/FUSChatCenterModule/FUSChatCenterModule/Features/InstantMessaging/Other/FUSChatCallHelper.swift
Modules/FUSChatCenterModule/FUSChatCenterModule/Features/InstantMessaging/Other/FUSIMChatHttpHelper.h
Modules/FUSChatCenterModule/FUSChatCenterModule/Features/InstantMessaging/Other/FUSIMChatHttpHelper.m
Modules/FUSChatCenterModule/FUSChatCenterModule/Others/FUSChatCenterURLs.h
Modules/FUSChatCenterModule/FUSChatCenterModule/Others/FUSChatCenterURLs.m
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/Other/FUSLiveHelper.m
Modules/FUSChatCenterModule/FUSChatCenterModule/Features/InstantMessaging/Other/FUSChatCallHelper.swift
View file @
00aee5e3
...
...
@@ -11,7 +11,7 @@ import RxCocoa
import
FUSCommon
import
FUSFoundation
import
SJAttributesStringMaker
import
SwiftyJSON
@objcMembers
public
class
FUSChatCallHelper
:
NSObject
{
static
public
let
shared
=
FUSChatCallHelper
()
...
...
@@ -30,6 +30,8 @@ import SJAttributesStringMaker
let
paymentState
=
BehaviorRelay
<
FUSCallPaymentState
>
(
value
:
.
none
)
/// 是否是拨打者
let
isCaller
=
BehaviorRelay
<
Bool
>
(
value
:
false
)
/// 通话中对方的UID,没有通话是为空
let
callOtherUid
=
BehaviorRelay
<
String
?
>
(
value
:
nil
)
/// 是否是拨打者 OC
@objc
public
var
oc_isCaller
:
Bool
{
isCaller
.
value
}
/// 通话订单ID
...
...
@@ -121,8 +123,10 @@ import SJAttributesStringMaker
}
let
friendInfo
=
FUSZhaiXinDBOperate
.
fus_selectZhaiXinChatUserInfo
(
withUid
:
fid
)
if
friendInfo
!=
nil
{
self
.
otherFriendInfoIsReady
.
accept
(
friendInfo
)
self
.
callOtherUid
.
accept
(
fid
)
}
else
{
// 还没有用户信息,得重新拉
FUSZhaiXinDBOperate
.
fus_updateZhaiXinChatUserInfo
(
withUid
:
fid
)
{[
weak
self
]
model
in
...
...
@@ -138,7 +142,7 @@ import SJAttributesStringMaker
self
.
otherFriendInfoIsReady
.
distinctUntilChanged
()
.
timeout
(
.
seconds
(
10
),
scheduler
:
MainScheduler
.
instance
)
.
subscribe
(
onNext
:
{[
weak
self
]
model
in
print
(
model
?
.
uid
)
guard
let
model
=
model
else
{
return
}
if
model
.
uid
==
fid
{
FUSLoadingView
.
fus_dismissProgressView
()
...
...
@@ -247,29 +251,30 @@ import SJAttributesStringMaker
self
.
callOtherInfo
.
accept
(
friendInfo
)
}
self
.
createAgoraSession
()
// 发布通知
NotificationCenter
.
default
.
post
(
name
:
.
init
(
FUSChatPublicDefine
.
fus_imConversationCallDidComeNotification
()),
object
:
nil
)
// 弹出等待对方接听的视图
switch
type
{
case
.
none
:
// 啥也没有
break
case
.
audio
:
self
.
showVoiceCallView
(
isCaller
:
true
)
case
.
video
:
self
.
showVideoCallView
(
isCaller
:
true
)
default
:
break
}
self
.
state
.
accept
(
.
dialing
)
self
.
startCall
(
fid
:
fid
,
channelId
:
model
.
callId
,
type
:
type
)
{
success
in
self
.
createAgoraSession
(
toUid
:
fid
)
{
[
weak
self
]
in
guard
let
self
=
self
else
{
return
}
// 发布通知
NotificationCenter
.
default
.
post
(
name
:
.
init
(
FUSChatPublicDefine
.
fus_imConversationCallDidComeNotification
()),
object
:
nil
)
}
// 弹出等待对方接听的视图
switch
type
{
case
.
none
:
// 啥也没有
break
case
.
audio
:
self
.
showVoiceCallView
(
isCaller
:
true
)
case
.
video
:
self
.
showVideoCallView
(
isCaller
:
true
)
default
:
break
}
self
.
state
.
accept
(
.
dialing
)
self
.
startCall
(
fid
:
fid
,
channelId
:
model
.
callId
,
type
:
type
)
{
success
in
}
}
}
failure
:
{[
weak
self
]
msg
,
code
in
// ludy: 这里我想优化,合并所有的failure,但是问题是它所有的failure需要处理的结果不一样,比如没开始生成订单,那么就直接清空数据就行了,如果生成了订单,需要走endcall,然后如果已经接通了,还得不清空不endcall,让他去充值,类型太多,优化以后再说
switch
code
{
...
...
@@ -514,6 +519,7 @@ import SJAttributesStringMaker
self
.
isCaller
.
accept
(
false
)
let
friendInfo
=
FUSZhaiXinDBOperate
.
fus_selectZhaiXinChatUserInfo
(
withUid
:
fromUid
)
self
.
callOtherInfo
.
accept
(
friendInfo
)
self
.
callOtherUid
.
accept
(
fromUid
)
self
.
callFrom
.
accept
(
from
)
self
.
callType
.
accept
(
type
)
self
.
callOrderId
.
accept
(
orderId
)
...
...
@@ -521,32 +527,32 @@ import SJAttributesStringMaker
self
.
fus_getCurrentUserFollowState
()
self
.
createAgoraSession
()
// 弹出通话等待接听视图
var
callContent
=
""
if
type
==
.
video
{
self
.
showVideoCallView
(
isCaller
:
false
)
callContent
=
.
fus_localString
(
"邀请你进行视讯"
)
}
else
if
type
==
.
audio
{
self
.
showVoiceCallView
(
isCaller
:
false
)
callContent
=
.
fus_localString
(
"邀请你进行声优聊天"
)
}
// 发送通知
FUSIMChatService
.
shareInstance
()
.
fus_sendLocalNotification
(
withIsConversation
:
true
,
uid
:
fromUid
,
nick
:
self
.
callOtherInfo
.
value
?
.
nickname
??
""
,
pushContent
:
callContent
)
// 发布通知
// NotificationCenter.default.post(name: .init(SingleChatNotification.startVChatNotification), object: nil)
NotificationCenter
.
default
.
post
(
name
:
.
init
(
FUSChatPublicDefine
.
fus_imConversationCallDidComeNotification
()),
object
:
nil
)
// 如果在观看直播中,最小化直播间
if
FUSConfig
.
sharedInstanced
()
.
liveConfigs
.
isInRoom
&&
FUSConfig
.
sharedInstanced
()
.
liveConfigs
.
isAudience
{
FUSRouter
.
live
()
.
fus_minimizeLiveCompletion
{
self
.
createAgoraSession
(
toUid
:
fromUid
)
{[
weak
self
]
in
guard
let
self
=
self
else
{
return
}
// 弹出通话等待接听视图
var
callContent
=
""
if
type
==
.
video
{
self
.
showVideoCallView
(
isCaller
:
false
)
callContent
=
.
fus_localString
(
"邀请你进行视讯"
)
}
else
if
type
==
.
audio
{
self
.
showVoiceCallView
(
isCaller
:
false
)
callContent
=
.
fus_localString
(
"邀请你进行声优聊天"
)
}
// 发送通知
FUSIMChatService
.
shareInstance
()
.
fus_sendLocalNotification
(
withIsConversation
:
true
,
uid
:
fromUid
,
nick
:
self
.
callOtherInfo
.
value
?
.
nickname
??
""
,
pushContent
:
callContent
)
// 发布通知
// NotificationCenter.default.post(name: .init(SingleChatNotification.startVChatNotification), object: nil)
NotificationCenter
.
default
.
post
(
name
:
.
init
(
FUSChatPublicDefine
.
fus_imConversationCallDidComeNotification
()),
object
:
nil
)
// 如果在观看直播中,最小化直播间
if
FUSConfig
.
sharedInstanced
()
.
liveConfigs
.
isInRoom
&&
FUSConfig
.
sharedInstanced
()
.
liveConfigs
.
isAudience
{
FUSRouter
.
live
()
.
fus_minimizeLiveCompletion
{
}
}
}
}
failure
:
{
// 发送透传消息让对方挂断
FUSIMChatService
.
shareInstance
()
.
fus_sendPrivateCmdMsgToOtherUser
(
withUserID
:
fromUid
,
action
:
FUSIMMessageCMD
.
callerCancle
.
fus_valueString
(),
param
:
[
.
CallParam
.
callConnectFailOrderid
:
orderId
])
...
...
@@ -1085,84 +1091,94 @@ extension FUSChatCallHelper {
extension
FUSChatCallHelper
{
/// 创建session
private
func
createAgoraSession
()
{
private
func
createAgoraSession
(
toUid
:
String
,
succeed
:
@escaping
(()
->
Void
))
{
FUSLoadingView
.
fus_showProgressView
(
withMessage
:
""
)
agoraSession
?
.
destroy
()
agoraSession
=
.
init
()
self
.
callOtherVideoEnable
.
accept
(
self
.
callType
.
value
==
.
video
?
true
:
false
)
self
.
callVideoEnable
.
accept
(
self
.
callType
.
value
==
.
video
?
true
:
false
)
if
let
uid
=
self
.
callOtherInfo
.
value
?
.
uid
{
agoraSession
?
.
remoteUidList
.
append
(
uid
)
}
if
self
.
callType
.
value
==
.
video
{
agoraSession
?
.
videoEnable
=
true
}
self
.
agoraSession
?
.
state
.
subscribe
(
onNext
:
{[
weak
self
]
state
in
guard
let
self
=
self
else
{
return
}
switch
state
{
case
.
connecting
:
// 对方加入频道判定为连接中
self
.
state
.
accept
(
.
connecting
)
// self.answerOutOftimeDisposeBag = .init()
case
let
.
offline
(
reason
,
uid
):
// 掉线处理
switch
reason
{
case
.
quit
,
.
dropped
:
if
uid
==
self
.
callOtherInfo
.
value
?
.
uid
.
uintValue
{
self
.
endCall
(
reason
:
.
hangUpPassivity
)
FUSIMChatHttpHelper
.
fus_requestOneToOneGetRTCData
(
withRoomId
:
toUid
)
{[
weak
self
]
dictData
in
FUSLoadingView
.
fus_dismissProgressView
()
guard
let
self
=
self
else
{
return
}
let
rtcData
=
FUSRtcData
.
createFrom
(
JSON
(
dictData
as
Any
))
self
.
agoraSession
=
.
init
(
rtcData
:
rtcData
)
self
.
callOtherVideoEnable
.
accept
(
self
.
callType
.
value
==
.
video
?
true
:
false
)
self
.
callVideoEnable
.
accept
(
self
.
callType
.
value
==
.
video
?
true
:
false
)
if
let
uid
=
self
.
callOtherUid
.
value
{
self
.
agoraSession
?
.
remoteUidList
.
append
(
uid
)
}
if
self
.
callType
.
value
==
.
video
{
self
.
agoraSession
?
.
videoEnable
=
true
}
self
.
agoraSession
?
.
state
.
subscribe
(
onNext
:
{[
weak
self
]
state
in
guard
let
self
=
self
else
{
return
}
switch
state
{
case
.
connecting
:
// 对方加入频道判定为连接中
self
.
state
.
accept
(
.
connecting
)
// self.answerOutOftimeDisposeBag = .init()
case
let
.
offline
(
reason
,
uid
):
// 掉线处理
switch
reason
{
case
.
quit
,
.
dropped
:
if
uid
==
self
.
callOtherUid
.
value
?
.
uintValue
{
self
.
endCall
(
reason
:
.
hangUpPassivity
)
}
default
:
break
}
default
:
break
}
default
:
break
}
})
.
disposed
(
by
:
self
.
reuseDisposeBag
)
self
.
agoraSession
?
.
remoteVideoStateChange
.
subscribe
(
onNext
:
{[
weak
self
]
model
in
guard
let
self
=
self
else
{
return
}
guard
model
.
uid
==
self
.
callOtherInfo
.
value
?
.
uid
??
""
else
{
return
}
if
model
.
state
==
.
stopped
&&
model
.
reason
==
.
remoteMuted
{
// 对方点击了关闭
self
.
callOtherVideoEnable
.
accept
(
false
)
}
else
if
model
.
state
==
.
decoding
&&
model
.
reason
==
.
remoteUnmuted
{
// 对方点击了开启视频
self
.
callOtherVideoEnable
.
accept
(
true
)
}
// else if model.state == .frozen &&
// model.reason == .congestion{
// // 对方下线
// self.endCall(reason: .otherOutOfLine)
// }
})
.
disposed
(
by
:
self
.
reuseDisposeBag
)
self
.
callVideoEnable
.
subscribe
(
onNext
:
{[
weak
self
]
callVideoEnable
in
self
?
.
agoraSession
?
.
videoEnable
=
callVideoEnable
})
.
disposed
(
by
:
self
.
reuseDisposeBag
)
if
self
.
isCaller
.
value
==
true
{
Observable
.
combineLatest
(
self
.
paymentState
,
self
.
stateCallTime
)
.
filter
({
connectingState
,
stateCallTime
in
return
connectingState
==
.
startCharging
})
.
subscribe
(
onNext
:
{[
weak
self
]
connectingState
,
stateCallTime
in
})
.
disposed
(
by
:
self
.
reuseDisposeBag
)
self
.
agoraSession
?
.
remoteVideoStateChange
.
subscribe
(
onNext
:
{[
weak
self
]
model
in
guard
let
self
=
self
else
{
return
}
guard
model
.
uid
==
self
.
callOtherUid
.
value
??
""
else
{
return
}
if
stateCallTime
!=
0
&&
stateCallTime
%
60
==
0
{
self
?
.
fus_onetooneCallConsume
()
if
model
.
state
==
.
stopped
&&
model
.
reason
==
.
remoteMuted
{
// 对方点击了关闭
self
.
callOtherVideoEnable
.
accept
(
false
)
}
else
if
model
.
state
==
.
decoding
&&
(
model
.
reason
==
.
remoteUnmuted
||
model
.
reason
==
.
localUnmuted
)
{
// 对方点击了开启视频
self
.
callOtherVideoEnable
.
accept
(
true
)
}
})
.
disposed
(
by
:
self
.
reuseDisposeBag
)
self
.
callVideoEnable
.
subscribe
(
onNext
:
{[
weak
self
]
callVideoEnable
in
self
?
.
agoraSession
?
.
videoEnable
=
callVideoEnable
})
.
disposed
(
by
:
self
.
reuseDisposeBag
)
if
self
.
isCaller
.
value
==
true
{
Observable
.
combineLatest
(
self
.
paymentState
,
self
.
stateCallTime
)
.
filter
({
paymentState
,
stateCallTime
in
return
paymentState
==
.
startCharging
})
.
subscribe
(
onNext
:
{[
weak
self
]
paymentState
,
stateCallTime
in
if
stateCallTime
!=
0
&&
stateCallTime
%
60
==
0
{
self
?
.
fus_onetooneCallConsume
()
}
})
.
disposed
(
by
:
self
.
reuseDisposeBag
)
}
//TODO: 索隆 - V57
// self.readLocal()
succeed
()
}
failure
:
{[
weak
self
]
msg
,
code
in
// 其他情况统一为通话失败
self
!.
endCall
(
reason
:
.
failedNeedNotice
)
FUSDialogView
.
fus_showDialog
(
msg
)
}
}
func
fus_checkQualification
(
fid
:
String
,
calltype
:
FUSAgoraSessionType
,
success
:(()
->
Void
)?)
{
...
...
@@ -1282,7 +1298,7 @@ extension FUSChatCallHelper {
let
fid
=
callOtherInfo
.
value
?
.
uid
??
""
let
orderid
=
callOrderId
.
value
??
""
var
resultStr
=
""
var
dialog
=
""
// var isUnaccepted = false
...
...
@@ -1622,6 +1638,7 @@ extension FUSChatCallHelper {
otherFriendInfoIsReady
.
accept
(
nil
)
state
.
accept
(
.
idle
)
callOtherUid
.
accept
(
nil
)
isCaller
.
accept
(
false
)
callOrderId
.
accept
(
nil
)
callOtherInfo
.
accept
(
nil
)
...
...
Modules/FUSChatCenterModule/FUSChatCenterModule/Features/InstantMessaging/Other/FUSIMChatHttpHelper.h
View file @
00aee5e3
...
...
@@ -194,4 +194,10 @@
+
(
void
)
fus_requestOneToOneCallConnectSuccessWith
:(
NSString
*
)
callId
success
:(
void
(
^
)(
void
))
success
failure
:(
void
(
^
)(
NSString
*
,
int
))
failure
;
/// 1对1 获取rtcdata
+
(
void
)
fus_requestOneToOneGetRTCDataWithRoomId
:(
NSString
*
)
roomId
succeed
:(
void
(
^
)(
NSDictionary
*
dataDict
))
succeed
failure
:(
void
(
^
)(
NSString
*
msg
,
int
code
))
failure
;
@end
Modules/FUSChatCenterModule/FUSChatCenterModule/Features/InstantMessaging/Other/FUSIMChatHttpHelper.m
View file @
00aee5e3
...
...
@@ -432,4 +432,30 @@
}];
}
/// 1对1 获取rtcdata
+
(
void
)
fus_requestOneToOneGetRTCDataWithRoomId
:(
NSString
*
)
roomId
succeed
:(
void
(
^
)(
NSDictionary
*
dataDict
))
succeed
failure
:(
void
(
^
)(
NSString
*
msg
,
int
code
))
failure
{
if
([
NSString
isNull
:
roomId
])
{
if
(
failure
)
failure
(
nil
,
ERROR_CODE
);
return
;
}
NSDictionary
*
params
=
@{
@"toUid"
:
roomId
};
[
FUSHttpHelper
postRequestBinaryWithUrl
:
FUSChatCenterURLs
.
fus_URL_oneToOneRtcData
params
:
params
success
:^
(
NSDictionary
*
dataDict
,
int
code
)
{
if
(
succeed
)
{
succeed
(
dataDict
);
}
}
failure
:^
(
NSDictionary
*
dataDict
,
int
code
)
{
if
(
failure
)
failure
(
FAILURE_MESSAGE
,
code
);
}];
}
@end
Modules/FUSChatCenterModule/FUSChatCenterModule/Others/FUSChatCenterURLs.h
View file @
00aee5e3
...
...
@@ -157,6 +157,8 @@ NS_ASSUME_NONNULL_BEGIN
/// 1对1私房接听被叫方连接成功
+
(
NSString
*
)
fus_URL_oneToOneCallConnectSuccess
;
/// 1对1 获取rtcdata
+
(
NSString
*
)
fus_URL_oneToOneRtcData
;
@end
...
...
Modules/FUSChatCenterModule/FUSChatCenterModule/Others/FUSChatCenterURLs.m
View file @
00aee5e3
...
...
@@ -238,4 +238,10 @@
+
(
NSString
*
)
fus_URL_oneToOneCallConnectSuccess
{
return
[
FUSConfig
.
sharedInstanced
.
pathConfigs
apiUrl
:
@"/onetoone/call/connect/success"
];
}
/// 1对1 获取rtcdata
+
(
NSString
*
)
fus_URL_oneToOneRtcData
{
return
[
FUSConfig
.
sharedInstanced
.
pathConfigs
apiUrl
:
@"/onetoone/rtcdata/get"
];
}
@end
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/Other/FUSLiveHelper.m
View file @
00aee5e3
...
...
@@ -106,7 +106,7 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor
#pragma mark - 获取rtcData
-
(
void
)
fus_getRTCDataWithForceUpdate
:
(
BOOL
)
forceUpdate
{
[
FUSLiveHttpHelper
fus_requestliveGetRTCData
:[
FUSCacheDataShare
shareStore
].
userDetailInfo
.
ui
d
Success
:
^
(
NSDictionary
*
_Nonnull
dataDict
)
{
[
FUSLiveHttpHelper
fus_requestliveGetRTCData
:[
FUSCacheDataShare
shareStore
].
userDetailInfo
.
roomI
d
Success
:
^
(
NSDictionary
*
_Nonnull
dataDict
)
{
if
(
FUSLiveHelper
.
shareInstance
.
liveRTCData
==
nil
)
{
FUSLiveRTCData
*
data
=
[
FUSLiveRTCData
createFromArchieveWithKey
:
KLiveDataCenter_store_liveRTCData
];
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment