forked from mirrors/linphone-iphone
Record call
This commit is contained in:
parent
5c7d76a572
commit
96bdf5150c
8 changed files with 97 additions and 20 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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!")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue