Add voiceRecorder

This commit is contained in:
Benoit Martins 2023-02-10 09:50:45 +01:00 committed by QuentinArguillere
parent 7368d07440
commit af9339fe23
4 changed files with 138 additions and 37 deletions

View file

@ -154,6 +154,10 @@ import AVFoundation
@objc var sharingMedia : Bool = false
var isVoiceRecording : Bool = false
var voiceRecorder : OpaquePointer? = nil
var showVoiceRecorderView : Bool = false
var vrRecordTimer = Timer()
var isPendingVoiceRecord = false
override func viewDidLoad() {
super.viewDidLoad(
@ -188,6 +192,9 @@ import AVFoundation
tableController.toggleSelectionButton = action1SelectAllButton
messageView.sendButton.onClickAction = onSendClick
messageView.pictureButton.onClickAction = alertAction
messageView.voiceRecordButton.onClickAction = onVrStart
recordingStopButton.onClickAction = stopVoiceRecording
recordingDeleteButton.onClickAction = cancelVoiceRecording
chatRoomDelegate = ChatRoomDelegateStub(
@ -859,6 +866,19 @@ import AVFoundation
}
}
func setRecordingVisible(visible : Bool) {
var isBottomOfView = false
if (tableController.tableView.contentOffset.y + 1) >= (tableController.tableView.contentSize.height - tableController.tableView.frame.size.height) {
isBottomOfView = true
}
UIView.animate(withDuration: 0.3, animations: {
self.recordingView.isHidden = visible
})
if(isBottomOfView){
tableController.scroll(toBottom: false)
}
}
func initReplyView(_ visible: Bool, message: OpaquePointer?) {
if visible {
let addresses = ChatMessage.getSwiftObject(cObject: message!).fromAddress
@ -1596,8 +1616,7 @@ import AVFoundation
return isBasic
}
/*
func onVrStart(_ sender: Any) {
func onVrStart() {
if isVoiceRecording {
stopVoiceRecording()
} else {
@ -1606,66 +1625,97 @@ import AVFoundation
}
func createVoiceRecorder() {
let p = linphone_core_create_recorder_params(LC)
let p = linphone_core_create_recorder_params(LinphoneManager.getLc())
linphone_recorder_params_set_file_format(p, LinphoneRecorderFileFormatMkv)
voiceRecorder = linphone_core_create_recorder(LC, p)
voiceRecorder = linphone_core_create_recorder(LinphoneManager.getLc(), p)
}
func startVoiceRecording() {
UIApplication.shared.isIdleTimerDisabled = true
if !voiceRecorder {
setRecordingVisible(visible: false)
if (voiceRecorder == nil) {
createVoiceRecorder()
}
CallManager.instance.activateAudioSession()
toggleRecord.selected = true
vrPlayButton.setImage(UIImage(named: "vr_stop"), for: .normal)
CallManager.instance().activateAudioSession()
messageView.voiceRecordButton.isSelected = true
recordingStopButton.isHidden = false
recordingPlayButton.isHidden = true
showVoiceRecorderView = true
updateFramesInclRecordingAndReplyView()
isVoiceRecording = true
vrWaveMaskPlayer.frame = CGRect.zero
//vrWaveMaskPlayer.frame = CGRect.zero
switch linphone_recorder_get_state(voiceRecorder) {
case LinphoneRecorderClosed:
let filename = "\(LinphoneManager.imagesDirectory())/voice-recording-\(UUID().uuidString).mkv"
linphone_recorder_open(voiceRecorder, filename.utf8CString)
let filename = "\(String(describing: LinphoneManager.imagesDirectory()))/voice-recording-\(UUID().uuidString).mkv"
linphone_recorder_open(voiceRecorder, filename)
linphone_recorder_start(voiceRecorder)
LOGW("[Chat Message Sending] Recorder is closed opening it with %@", filename)
print("[Chat Message Sending] Recorder is closed opening it with \(filename)")
case LinphoneRecorderRunning:
LOGW("[Chat Message Sending] Recorder is already recording")
print("[Chat Message Sending] Recorder is already recording")
case LinphoneRecorderPaused:
LOGW("[Chat Message Sending] Recorder isn't closed, resuming recording")
print("[Chat Message Sending] Recorder isn't closed, resuming recording")
linphone_recorder_start(voiceRecorder)
default:
break
}
vrWaveMask.frame = vrWave.frame
vrDurationLabel.text = formattedDuration(linphone_recorder_get_duration(voiceRecorder))
vrRecordTimer = Timer.scheduledTimer(
timeInterval: 1.0,
target: self,
selector: Selector("voiceRecordTimerUpdate"),
userInfo: nil,
repeats: true)
recordingWaveImageMask.frame = recordingWaveImage.frame
recordingDurationTextView.text = ChatConversationViewSwift.formattedDuration(Int(linphone_recorder_get_duration(voiceRecorder)))
vrRecordTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
self.voiceRecordTimerUpdate()
}
}
func voiceRecordTimerUpdate() {
let recorderDuration = linphone_recorder_get_duration(voiceRecorder)
if recorderDuration > LinphoneManager.instance().lpConfigInt(forKey: "voice_recording_max_duration", withDefault: 60000) {
print("[Chat Message Sending] Max duration for voice recording exceeded, stopping. (max = %d)", LinphoneManager.instance().lpConfigInt(forKey: "voice_recording_max_duration", withDefault: 60000))
stopVoiceRecording()
} else {
recordingDurationTextView.text = ChatConversationViewSwift.formattedDuration(Int(linphone_recorder_get_duration(voiceRecorder)))
var r = recordingWaveImageMask.frame
//recordingWaveImageMask.frame = CGRect(x: r.origin.x+r.size.width, y: r.origin.y, width: 0, height: r.size.height)
//r.origin.x += 20
//r.size.width -= 20
//r = CGRect(x: r.origin.x-200, y: r.origin.y, width: r.size.width+200, height: r.size.height)
r = CGRect(x: r.origin.x-200, y: r.origin.y, width: r.size.width, height: r.size.height)
if r.origin.x > recordingWaveImage.frame.size.width {
r = recordingWaveImage.frame
recordingWaveImageMask.frame = r
} else {
UIView.animate(withDuration: 1.0, delay: 0.0, options: .curveLinear, animations: {
//self.recordingWaveImageMask.frame = r
self.recordingWaveImageMask.transform = CGAffineTransform(scaleX: 0.1, y: 1)
//self.recordingWaveImageMask.transform = CGAffineTransform(translationX: 100, y: 1)
//self.recordingWaveImageMask.frame = CGRect(x: 0, y: r.origin.y, width: 10, height: r.size.height)
}) { finished in
}
}
}
}
func stopVoiceRecording() {
UIApplication.shared.isIdleTimerDisabled = false
if voiceRecorder && linphone_recorder_get_state(voiceRecorder) == LinphoneRecorderRunning {
LOGI("[Chat Message Sending] Pausing / closing voice recorder")
if (voiceRecorder != nil) && linphone_recorder_get_state(voiceRecorder) == LinphoneRecorderRunning {
print("[Chat Message Sending] Pausing / closing voice recorder")
linphone_recorder_pause(voiceRecorder)
linphone_recorder_close(voiceRecorder)
vrDurationLabel.text = formattedDuration(linphone_recorder_get_duration(voiceRecorder))
recordingDurationTextView.text = ChatConversationViewSwift.formattedDuration(Int(linphone_recorder_get_duration(voiceRecorder)))
}
isVoiceRecording = false
if LinphoneManager.instance.lpConfigBool(forKey: "voice_recording_send_right_away", withDefault: false) {
onSendClick(nil)
if LinphoneManager.instance().lpConfigBool(forKey: "voice_recording_send_right_away", withDefault: false) {
onSendClick()
}
vrPlayButton.setImage(UIImage(named: "vr_play"), for: .normal)
toggleRecord.selected = false
vrWaveMask.frame = CGRect.zero
recordingStopButton.isHidden = true
recordingPlayButton.isHidden = false
messageView.voiceRecordButton.isSelected = false
recordingWaveImageMask.frame = CGRect.zero
vrRecordTimer.invalidate()
isPendingVoiceRecord = linphone_recorder_get_duration(voiceRecorder) > 0
setSendButtonState()
@ -1674,18 +1724,24 @@ import AVFoundation
func cancelVoiceRecording() {
UIApplication.shared.isIdleTimerDisabled = false
setRecordingVisible(visible: true)
recordingStopButton.isHidden = false
recordingPlayButton.isHidden = true
showVoiceRecorderView = false
toggleRecord.selected = false
updateFramesInclRecordingAndReplyView()
messageView.voiceRecordButton.isSelected = false
isPendingVoiceRecord = false
isVoiceRecording = false
if voiceRecorder && linphone_recorder_get_state(voiceRecorder) != LinphoneRecorderClosed {
if (voiceRecorder != nil) && linphone_recorder_get_state(voiceRecorder) != LinphoneRecorderClosed {
linphone_recorder_close(voiceRecorder)
let recordingFile = linphone_recorder_get_file(voiceRecorder)
if let recordingFile {
AppManager.removeFile(withFile: String(utf8String: recordingFile))
AppManager.removeFile(file: String(utf8String: recordingFile)!)
}
}
setSendButtonState()
}*/
}
func setSendButtonState() {
//sendButton.enabled = !isVoiceRecording && ((isPendingVoiceRecord && linphone_recorder_get_duration(voiceRecorder) > 0) || messageField.text().length() > 0 || fileContext.count > 0)
}
}

View file

@ -60,6 +60,8 @@ class MessageView: UIView, UITextViewDelegate {
addSubview(voiceRecordButton)
voiceRecordButton.toRightOf(pictureButton, withLeftMargin: 10).matchParentHeight().done()
voiceRecordButton.size(w: 30, h: 30).done()
voiceRecordButton.setImage(UIImage(named:"vr_off.png"), for: .normal)
voiceRecordButton.setImage(UIImage(named:"vr_on.png"), for: .selected)
voiceRecordButton.onClickAction = action3
addSubview(ephemeralIndicator)

View file

@ -44,6 +44,14 @@ import SnapKit
let replyContentForMeetingTextView = StyledLabel(VoipTheme.chat_conversation_reply_content)
let replyDeleteButton = CallControlButton(width: 22, height: 22, buttonTheme:VoipTheme.nav_black_button("reply_cancel"))
let replyMeetingSchedule = UIImageView()
let recordingView = UIView()
let recordingDeleteButton = CallControlButton(width: 40, height: 40, buttonTheme:VoipTheme.nav_black_button("delete_default"))
let recordingPlayButton = CallControlButton(width: 40, height: 40, buttonTheme:VoipTheme.nav_black_button("vr_play"))
let recordingStopButton = CallControlButton(width: 40, height: 40, buttonTheme:VoipTheme.nav_black_button("vr_stop"))
let recordingWaveView = UIView()
let recordingDurationTextView = StyledLabel(VoipTheme.chat_conversation_recording_duration)
let recordingWaveImage = UIImageView(image: UIImage(named: "vr_wave.png"))
let recordingWaveImageMask = UIView()
let messageView = MessageView()
let mediaSelector = UIView()
let mediaSelectorReply = UIView()
@ -210,6 +218,40 @@ import SnapKit
replyBubble.addSubview(replyDeleteButton)
replyDeleteButton.alignParentRight(withMargin: 15).centerY().done()
stackView.addArrangedSubview(recordingView)
recordingView.height(top_bar_height).wrapContentY().matchParentSideBorders().done()
recordingView.backgroundColor = VoipTheme.voipToolbarBackgroundColor.get()
recordingView.isHidden = true
recordingView.addSubview(recordingDeleteButton)
recordingDeleteButton.alignParentLeft(withMargin: 10).matchParentHeight().done()
recordingView.addSubview(recordingPlayButton)
recordingPlayButton.alignParentRight(withMargin: 10).matchParentHeight().done()
recordingPlayButton.isHidden = true
recordingView.addSubview(recordingStopButton)
recordingStopButton.alignParentRight(withMargin: 10).matchParentHeight().done()
recordingView.addSubview(recordingWaveView)
recordingWaveView.toRightOf(recordingDeleteButton, withLeftMargin: 10).toLeftOf(recordingStopButton, withRightMargin: 10).alignParentTop(withMargin: 10).alignParentBottom(withMargin: 10).done()
recordingWaveView.layer.cornerRadius = 5
recordingWaveView.backgroundColor = VoipTheme.backgroundWhiteBlack.get()
recordingWaveView.addSubview(recordingDurationTextView)
recordingDurationTextView.alignParentRight(withMargin: 10).matchParentHeight().done()
recordingWaveView.addSubview(recordingWaveImage)
recordingWaveImage.alignParentTop(withMargin: 10).alignParentBottom(withMargin: 10).alignParentLeft(withMargin: 10).toLeftOf(recordingDurationTextView, withRightMargin: 10).done()
recordingWaveView.addSubview(recordingWaveImageMask)
recordingWaveImageMask.alignParentTop(withMargin: 10).alignParentBottom(withMargin: 10).alignParentLeft(withMargin: 10).done() //toLeftOf(recordingDurationTextView, withRightMargin: 10).done()
recordingWaveImageMask.rightAnchor.constraint(equalTo: recordingDurationTextView.leftAnchor, constant: -10).isActive = true
recordingWaveImageMask.backgroundColor = .blue //VoipTheme.backgroundWhiteBlack.get()
stackView.addArrangedSubview(mediaSelector)
mediaSelector.height(top_bar_height*2).matchParentSideBorders().done()

View file

@ -150,6 +150,7 @@ import UIKit
static let chat_conversation_operation_in_progress_wait = TextStyle(fgColor: LightDarkColor(primary_color,primary_color), bgColor: LightDarkColor(.clear,.clear), allCaps: false, align: .center, font: fontName+"-Bold", size: 18.0)
static let chat_conversation_reply_label = TextStyle(fgColor: LightDarkColor(voip_dark_gray,.white), bgColor: LightDarkColor(.clear,.clear), allCaps: false, align: .left, font: fontName+"-Bold", size: 14.0)
static let chat_conversation_reply_content = TextStyle(fgColor: LightDarkColor(voip_dark_gray,.white), bgColor: LightDarkColor(.clear,.clear), allCaps: false, align: .left, font: fontName+"-Regular", size: 14.0)
static let chat_conversation_recording_duration = TextStyle(fgColor: LightDarkColor(voip_dark_gray,.white), bgColor: LightDarkColor(.clear,.clear), allCaps: false, align: .left, font: fontName+"-Regular", size: 20.0)
// Buttons Background (State colors)