Asymmetrical video call

This commit is contained in:
Benoit Martins 2024-04-09 14:00:41 +02:00
parent f771bdc790
commit 6c59bd6581
4 changed files with 51 additions and 84 deletions

View file

@ -19,6 +19,9 @@ upload_bw=0
[video]
size=vga
automatically_accept=1
automatically_initiate=0
automatically_accept_direction=2 #receive only
[app]
tunnel=disabled

View file

@ -44,7 +44,6 @@ class TelecomManager: ObservableObject {
@Published var callDisplayed: Bool = true
@Published var callStarted: Bool = false
@Published var outgoingCallStarted: Bool = false
@Published var remoteVideo: Bool = false
@Published var remoteConfVideo: Bool = false
@Published var isRecordingByRemote: Bool = false
@Published var isPausedByRemote: Bool = false
@ -213,6 +212,7 @@ class TelecomManager: ObservableObject {
if isSas {
lcallParams.mediaEncryption = .ZRTP
}
if isConference {
lcallParams.videoEnabled = true
/* if (ConferenceWaitingRoomViewModel.sharedModel.joinLayout.value! != .AudioOnly) {
@ -223,7 +223,8 @@ class TelecomManager: ObservableObject {
lcallParams.videoEnabled = false
}*/
} else {
lcallParams.videoEnabled = isVideo
lcallParams.videoEnabled = true
lcallParams.videoDirection = isVideo ? MediaDirection.SendRecv : MediaDirection.Inactive
}
if let call = core.inviteAddressWithParams(addr: addr, params: lcallParams) {
@ -256,7 +257,6 @@ class TelecomManager: ObservableObject {
func acceptCall(core: Core, call: Call, hasVideo: Bool) {
do {
let callParams = try core.createCallParams(call: call)
callParams.recordFile = makeRecordFilePath()
callParams.videoEnabled = hasVideo
/*if (ConfigManager.instance().lpConfigBoolForKey(key: "edge_opt_preference")) {
@ -283,7 +283,7 @@ class TelecomManager: ObservableObject {
// Prevent incoming group call to start in audio only layout
// Do the same as the conference waiting room
callParams.videoEnabled = true
callParams.videoDirection = core.videoActivationPolicy?.automaticallyInitiate == true ? .SendRecv : .RecvOnly
callParams.videoDirection = core.videoActivationPolicy?.automaticallyInitiate == true ? .SendRecv : .RecvOnly
Log.info("[Context] Enabling video on call params to prevent audio-only layout when answering")
}
@ -376,8 +376,7 @@ class TelecomManager: ObservableObject {
} else {
DispatchQueue.main.async {
let oldRemoteVideo = self.remoteVideo
//self.remoteVideo = (core.videoActivationPolicy?.automaticallyAccept ?? false) && (call.remoteParams?.videoEnabled ?? false)
let oldRemoteConfVideo = self.remoteConfVideo
if call.conference != nil {
if call.conference!.activeSpeakerParticipantDevice != nil {
@ -387,11 +386,14 @@ class TelecomManager: ObservableObject {
self.remoteConfVideo = true
}
} else {
self.remoteVideo = call.currentParams!.videoEnabled && call.currentParams!.videoDirection != MediaDirection.Inactive
self.remoteConfVideo = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.remoteConfVideo = call.currentParams!.videoEnabled && call.currentParams!.videoDirection == MediaDirection.SendRecv || call.currentParams!.videoDirection == MediaDirection.SendOnly
}
}
if self.remoteVideo && self.remoteVideo != oldRemoteVideo {
if self.remoteConfVideo && self.remoteConfVideo != oldRemoteConfVideo {
do {
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
} catch _ {
@ -399,7 +401,7 @@ class TelecomManager: ObservableObject {
}
}
if self.remoteVideo {
if self.remoteConfVideo {
Log.info("[Call] Remote video is activated")
}
@ -484,7 +486,7 @@ class TelecomManager: ObservableObject {
providerDelegate.callInfos.updateValue(callInfo!, forKey: uuid!)
providerDelegate.uuids.removeValue(forKey: callId)
providerDelegate.uuids.updateValue(uuid!, forKey: callInfo!.callId)
providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: remoteVideo, displayName: displayName)
providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: remoteConfVideo, displayName: displayName)
}
} else if TelecomManager.callKitEnabled(core: core) {
/*
@ -507,9 +509,9 @@ class TelecomManager: ObservableObject {
if uuid != nil {
// Tha app is now registered, updated the call already existed.
providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: remoteVideo, displayName: displayName)
providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: remoteConfVideo, displayName: displayName)
} else {
displayIncomingCall(call: call, handle: addr!.asStringUriOnly(), hasVideo: remoteVideo, callId: callId, displayName: displayName)
displayIncomingCall(call: call, handle: addr!.asStringUriOnly(), hasVideo: remoteConfVideo, callId: callId, displayName: displayName)
}
} /* else if UIApplication.shared.applicationState != .active {
// not support callkit , use notif

View file

@ -317,18 +317,7 @@ struct CallView: View {
.padding(.all, 10)
}
if !callViewModel.isConference && telecomManager.remoteVideo {
Button {
callViewModel.switchCamera()
} label: {
Image("camera-rotate")
.renderingMode(.template)
.resizable()
.foregroundStyle(.white)
.frame(width: 30, height: 30)
.padding(.horizontal)
}
} else if callViewModel.isConference && callViewModel.videoDisplayed {
if callViewModel.videoDisplayed {
Button {
callViewModel.switchCamera()
} label: {
@ -504,12 +493,12 @@ struct CallView: View {
.scaledToFill()
.clipped()
.onTapGesture {
if telecomManager.remoteVideo {
if callViewModel.videoDisplayed {
fullscreenVideo.toggle()
}
}
if telecomManager.remoteVideo {
if callViewModel.videoDisplayed && telecomManager.remoteConfVideo {
HStack {
Spacer()
VStack {
@ -619,7 +608,7 @@ struct CallView: View {
.scaledToFill()
.clipped()
.onTapGesture {
if telecomManager.remoteVideo {
if callViewModel.videoDisplayed {
fullscreenVideo.toggle()
}
}
@ -884,41 +873,22 @@ struct CallView: View {
Spacer()
if !callViewModel.isConference {
Button {
callViewModel.toggleVideo()
} label: {
HStack {
Image(telecomManager.remoteVideo ? "video-camera" : "video-camera-slash")
.renderingMode(.template)
.resizable()
.foregroundStyle((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray500 : .white)
.frame(width: 32, height: 32)
}
Button {
callViewModel.displayMyVideo()
} label: {
HStack {
Image(callViewModel.videoDisplayed ? "video-camera" : "video-camera-slash")
.renderingMode(.template)
.resizable()
.foregroundStyle((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray500 : .white)
.frame(width: 32, height: 32)
}
.buttonStyle(PressedButtonStyle())
.frame(width: 60, height: 60)
.background((callViewModel.isPaused || telecomManager.isPausedByRemote) ? .white : Color.gray500)
.cornerRadius(40)
.disabled(callViewModel.isPaused || telecomManager.isPausedByRemote)
} else {
Button {
callViewModel.displayMyVideo()
} label: {
HStack {
Image(callViewModel.videoDisplayed ? "video-camera" : "video-camera-slash")
.renderingMode(.template)
.resizable()
.foregroundStyle((callViewModel.isPaused || telecomManager.isPausedByRemote) ? Color.gray500 : .white)
.frame(width: 32, height: 32)
}
}
.buttonStyle(PressedButtonStyle())
.frame(width: 60, height: 60)
.background((callViewModel.isPaused || telecomManager.isPausedByRemote) ? .white : Color.gray500)
.cornerRadius(40)
.disabled(callViewModel.isPaused || telecomManager.isPausedByRemote)
}
.buttonStyle(PressedButtonStyle())
.frame(width: 60, height: 60)
.background((callViewModel.isPaused || telecomManager.isPausedByRemote) ? .white : Color.gray500)
.cornerRadius(40)
.disabled(callViewModel.isPaused || telecomManager.isPausedByRemote)
Button {
callViewModel.toggleMuteMicrophone()

View file

@ -295,42 +295,34 @@ class CallViewModel: ObservableObject {
}
}
func toggleVideo() {
coreContext.doOnCoreQueue { core in
if self.currentCall != nil {
do {
let params = try core.createCallParams(call: self.currentCall)
params.videoEnabled = !params.videoEnabled
Log.info(
"[CallViewModel] Updating call with video enabled set to \(params.videoEnabled)"
)
try self.currentCall!.update(params: params)
} catch {
}
}
}
}
func displayMyVideo() {
coreContext.doOnCoreQueue { core in
if self.currentCall != nil {
do {
let params = try core.createCallParams(call: self.currentCall)
params.videoEnabled = true
if params.videoEnabled {
if params.videoDirection == MediaDirection.SendRecv {
params.videoDirection = MediaDirection.RecvOnly
} else if params.videoDirection == MediaDirection.RecvOnly {
params.videoDirection = MediaDirection.SendRecv
if params.videoDirection == .SendRecv {
params.videoDirection = .RecvOnly
} else if params.videoDirection == .RecvOnly {
params.videoDirection = .SendRecv
} else if params.videoDirection == .SendOnly {
params.videoDirection = .Inactive
} else if params.videoDirection == .Inactive {
params.videoDirection = .SendOnly
}
}
try self.currentCall!.update(params: params)
let video = params.videoDirection == MediaDirection.SendRecv
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
let video = params.videoDirection == .SendRecv || params.videoDirection == .SendOnly
DispatchQueue.main.asyncAfter(deadline: .now() + (video ? 1 : 0)) {
if video {
self.videoDisplayed = false
}
self.videoDisplayed = video
}
} catch {