Record call

This commit is contained in:
Benoit Martins 2024-01-08 16:57:26 +01:00
parent 341d8171a0
commit db7ccff9f5
8 changed files with 97 additions and 20 deletions

View file

@ -104,7 +104,6 @@ final class CoreContext: ObservableObject {
self.mCore.videoCaptureEnabled = true
self.mCore.videoDisplayEnabled = true
self.mCore.recordAwareEnabled = true
let videoActivationPolicy = self.mCore.videoActivationPolicy!
videoActivationPolicy.automaticallyAccept = true

View file

@ -30,6 +30,7 @@ struct LinphoneApp: App {
@State private var historyViewModel: HistoryViewModel?
@State private var historyListViewModel: HistoryListViewModel?
@State private var startCallViewModel: StartCallViewModel?
@State private var callViewModel: CallViewModel?
var body: some Scene {
WindowGroup {
@ -43,13 +44,15 @@ struct LinphoneApp: App {
&& editContactViewModel != nil
&& historyViewModel != nil
&& historyListViewModel != nil
&& startCallViewModel != nil {
&& startCallViewModel != nil
&& callViewModel != nil {
ContentView(
contactViewModel: contactViewModel!,
editContactViewModel: editContactViewModel!,
historyViewModel: historyViewModel!,
historyListViewModel: historyListViewModel!,
startCallViewModel: startCallViewModel!
startCallViewModel: startCallViewModel!,
callViewModel: callViewModel!
)
} else {
SplashScreen()
@ -62,6 +65,7 @@ struct LinphoneApp: App {
historyViewModel = HistoryViewModel()
historyListViewModel = HistoryListViewModel()
startCallViewModel = StartCallViewModel()
callViewModel = CallViewModel()
}
}
}

View file

@ -209,9 +209,11 @@ extension ProviderDelegate: CXProviderDelegate {
let callInfo = callInfos[uuid]
let callId = callInfo?.callId ?? ""
DispatchQueue.main.async {
withAnimation {
TelecomManager.shared.callInProgress = true
if TelecomManager.shared.callInProgress == false {
DispatchQueue.main.async {
withAnimation {
TelecomManager.shared.callInProgress = true
}
}
}
CoreContext.shared.doOnCoreQueue { core in

View file

@ -42,6 +42,8 @@ class TelecomManager: ObservableObject {
@Published var callInProgress: Bool = false
@Published var callStarted: Bool = false
@Published var remoteVideo: Bool = false
@Published var isRemoteRecording: Bool = false
var actionToFulFill: CXCallAction?
var callkitAudioSessionActivated: Bool?
@ -125,6 +127,19 @@ class TelecomManager: ObservableObject {
}
}
}
private func makeRecordFilePath() -> String{
var filePath = "recording_"
let now = Date()
let dateFormat = DateFormatter()
dateFormat.dateFormat = "E-d-MMM-yyyy-HH-mm-ss"
let date = dateFormat.string(from: now)
filePath = filePath.appending("\(date).mkv")
let paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)
let writablePath = paths[0]
return writablePath.appending("/\(filePath)")
}
func doCall(core: Core, addr: Address, isSas: Bool, isVideo: Bool, isConference: Bool = false) throws {
// let displayName = FastAddressBook.displayName(for: addr.getCobject)
@ -154,6 +169,9 @@ class TelecomManager: ObservableObject {
// let writablePath = AppManager.recordingFilePathFromCall(address: addr.username! )
// Log.directLog(BCTBX_LOG_DEBUG, text: "record file path: \(writablePath)")
// lcallParams.recordFile = writablePath
lcallParams.recordFile = makeRecordFilePath()
if isSas {
lcallParams.mediaEncryption = .ZRTP
}
@ -184,9 +202,12 @@ class TelecomManager: ObservableObject {
}
DispatchQueue.main.async {
self.callStarted = true
withAnimation {
self.callInProgress = true
if self.callInProgress == false {
withAnimation {
self.callInProgress = true
}
}
}
}
@ -195,6 +216,8 @@ 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")) {
let low_bandwidth = (AppManager.network() == .network_2g)
@ -311,12 +334,22 @@ class TelecomManager: ObservableObject {
if cstate == .PushIncomingReceived {
displayIncomingCall(call: call, handle: "Calling", hasVideo: false, callId: callId, displayName: "Calling")
} else {
let video = (core.videoActivationPolicy?.automaticallyAccept ?? false) && (call.remoteParams?.videoEnabled ?? false)
remoteVideo = (core.videoActivationPolicy?.automaticallyAccept ?? false) && (call.remoteParams?.videoEnabled ?? false)
if video {
if remoteVideo {
Log.info("[Call] Remote video is activated")
}
isRemoteRecording = call.remoteParams?.isRecording ?? false
if isRemoteRecording && ToastViewModel.shared.toastMessage == "" {
ToastViewModel.shared.toastMessage = "\(call.remoteAddress) is recording"
ToastViewModel.shared.displayToast.toggle()
Log.info("[Call] Call is recording by \(call.remoteAddress)")
}
if call.userData == nil {
let appData = CallAppData()
TelecomManager.setAppData(sCall: call, appData: appData)
@ -351,7 +384,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: video, displayName: displayName)
providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: remoteVideo, displayName: displayName)
}
} else if TelecomManager.callKitEnabled(core: core) {
/*
@ -374,9 +407,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: video, displayName: displayName)
providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: remoteVideo, displayName: displayName)
} else {
displayIncomingCall(call: call, handle: addr!.asStringUriOnly(), hasVideo: video, callId: callId, displayName: displayName)
displayIncomingCall(call: call, handle: addr!.asStringUriOnly(), hasVideo: remoteVideo, callId: callId, displayName: displayName)
}
} /* else if UIApplication.shared.applicationState != .active {
// not support callkit , use notif

View file

@ -273,7 +273,7 @@ struct CallView: View {
.frame(width: 32, height: 32)
}
.frame(width: 60, height: 60)
.background(Color.gray500)
.background(callViewModel.isRecording ? Color.redDanger500 : Color.gray500)
.cornerRadius(40)
Text("Record")
@ -572,6 +572,28 @@ struct CallView: View {
)
}
if callViewModel.isRecording {
HStack {
VStack {
Image("record-fill")
.renderingMode(.template)
.resizable()
.foregroundStyle(Color.redDanger500)
.frame(width: 32, height: 32)
.padding(10)
.if(fullscreenVideo) { view in
view.padding(.top, 30)
}
Spacer()
}
Spacer()
}
.frame(
maxWidth: fullscreenVideo ? geometry.size.width : geometry.size.width - 8,
maxHeight: fullscreenVideo ? geometry.size.height + geometry.safeAreaInsets.top + geometry.safeAreaInsets.bottom : geometry.size.height - 140
)
}
if !telecomManager.callStarted && !fullscreenVideo {
VStack {
ActivityIndicator()

View file

@ -33,6 +33,8 @@ class CallViewModel: ObservableObject {
@Published var avatarModel: ContactAvatarModel?
@Published var micMutted: Bool = false
@Published var cameraDisplayed: Bool = false
@Published var isRecording: Bool = false
@Published var isRemoteRecording: Bool = false
@State var timeElapsed: Int = 0
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@ -40,7 +42,6 @@ class CallViewModel: ObservableObject {
var currentCall: Call?
init() {
do {
try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .voiceChat, options: .allowBluetooth)
try AVAudioSession.sharedInstance().setActive(true)
@ -48,6 +49,10 @@ class CallViewModel: ObservableObject {
}
resetCallView()
}
func resetCallView() {
coreContext.doOnCoreQueue { core in
if core.currentCall != nil && core.currentCall!.remoteAddress != nil {
self.currentCall = core.currentCall
@ -70,6 +75,7 @@ class CallViewModel: ObservableObject {
//self.avatarModel = ???
self.micMutted = self.currentCall!.microphoneMuted
self.cameraDisplayed = self.currentCall!.cameraEnabled == true
self.isRecording = self.currentCall!.params!.isRecording
}
}
}
@ -164,10 +170,9 @@ class CallViewModel: ObservableObject {
} else {
Log.info("[CallViewModel] Starting call recording \(self.currentCall!.params!.isRecording)")
self.currentCall!.startRecording()
Log.info("[CallViewModel] Starting call recording \(self.currentCall!.params!.isRecording)")
}
//var recording = self.currentCall!.params!.isRecording
//isRecording.postValue(recording)
self.isRecording = self.currentCall!.params!.isRecording
}
}
}

View file

@ -38,6 +38,7 @@ struct ContentView: View {
@ObservedObject var historyViewModel: HistoryViewModel
@ObservedObject var historyListViewModel: HistoryListViewModel
@ObservedObject var startCallViewModel: StartCallViewModel
@ObservedObject var callViewModel: CallViewModel
@State var index = 0
@State private var orientation = UIDevice.current.orientation
@ -661,9 +662,12 @@ struct ContentView: View {
}
if telecomManager.callInProgress {
CallView(callViewModel: CallViewModel())
CallView(callViewModel: callViewModel)
.zIndex(3)
.transition(.scale.combined(with: .move(edge: .top)))
.onAppear {
callViewModel.resetCallView()
}
}
// if sharedMainViewModel.displayToast {
@ -722,7 +726,8 @@ struct ContentView: View {
editContactViewModel: EditContactViewModel(),
historyViewModel: HistoryViewModel(),
historyListViewModel: HistoryListViewModel(),
startCallViewModel: StartCallViewModel()
startCallViewModel: StartCallViewModel(),
callViewModel: CallViewModel()
)
}
// swiftlint:enable type_body_length

View file

@ -54,6 +54,13 @@ struct ToastView: View {
.foregroundStyle(Color.greenSuccess500)
.default_text_style(styleSize: 15)
.padding(8)
case let str where str.contains("is recording"):
Text(toastViewModel.toastMessage)
.multilineTextAlignment(.center)
.foregroundStyle(Color.redDanger500)
.default_text_style(styleSize: 15)
.padding(8)
case "Failed":
Text("Invalid QR code!")