mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-26 03:20:50 +02:00
merged element-ios 1.10.5 into 4409_basis_update_1_10_5
This commit is contained in:
@@ -53,7 +53,7 @@ class VoiceMessageAudioPlayer: NSObject {
|
||||
return false
|
||||
}
|
||||
|
||||
return (audioPlayer.rate > 0)
|
||||
return audioPlayer.currentItem != nil && (audioPlayer.rate > 0)
|
||||
}
|
||||
|
||||
var duration: TimeInterval {
|
||||
@@ -118,6 +118,13 @@ class VoiceMessageAudioPlayer: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
func reloadContentIfNeeded() {
|
||||
if let url, let audioPlayer, audioPlayer.currentItem == nil {
|
||||
self.url = nil
|
||||
loadContentFromURL(url)
|
||||
}
|
||||
}
|
||||
|
||||
func removeAllPlayerItems() {
|
||||
audioPlayer?.removeAllItems()
|
||||
}
|
||||
@@ -130,6 +137,8 @@ class VoiceMessageAudioPlayer: NSObject {
|
||||
func play() {
|
||||
isStopped = false
|
||||
|
||||
reloadContentIfNeeded()
|
||||
|
||||
do {
|
||||
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
|
||||
try AVAudioSession.sharedInstance().setActive(true)
|
||||
|
||||
@@ -73,15 +73,18 @@ class VoiceMessageAudioRecorder: NSObject, AVAudioRecorderDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func stopRecording() {
|
||||
func stopRecording(releaseAudioSession: Bool = true) {
|
||||
audioRecorder?.stop()
|
||||
do {
|
||||
try AVAudioSession.sharedInstance().setActive(false)
|
||||
} catch {
|
||||
delegateContainer.notifyDelegatesWithBlock { delegate in
|
||||
(delegate as? VoiceMessageAudioRecorderDelegate)?.audioRecorder(self, didFailWithError: VoiceMessageAudioRecorderError.genericError) }
|
||||
|
||||
if releaseAudioSession {
|
||||
MXLog.debug("[VoiceMessageAudioRecorder] stopRecording() - releasing audio session")
|
||||
do {
|
||||
try AVAudioSession.sharedInstance().setActive(false)
|
||||
} catch {
|
||||
delegateContainer.notifyDelegatesWithBlock { delegate in
|
||||
(delegate as? VoiceMessageAudioRecorderDelegate)?.audioRecorder(self, didFailWithError: VoiceMessageAudioRecorderError.genericError) }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func peakPowerForChannelNumber(_ channelNumber: Int) -> Float {
|
||||
|
||||
@@ -187,7 +187,10 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
|
||||
audioPlayer?.stop()
|
||||
audioRecorder?.stopRecording()
|
||||
|
||||
sendRecordingAtURL(temporaryFileURL)
|
||||
// As we only use a single temporary file, we have to rename it, otherwise it will be deleted once the file is sent and if another recording has been started meanwhile, it will fail.
|
||||
if let finalFileURL = finalizeRecordingAtURL(temporaryFileURL) {
|
||||
sendRecordingAtURL(finalFileURL)
|
||||
}
|
||||
|
||||
isInLockedMode = false
|
||||
updateUI()
|
||||
@@ -196,15 +199,25 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
|
||||
// MARK: - AudioRecorderDelegate
|
||||
|
||||
func audioRecorderDidStartRecording(_ audioRecorder: VoiceMessageAudioRecorder) {
|
||||
guard self.audioRecorder === audioRecorder else {
|
||||
return
|
||||
}
|
||||
notifiedRemainingTime = false
|
||||
updateUI()
|
||||
}
|
||||
|
||||
func audioRecorderDidFinishRecording(_ audioRecorder: VoiceMessageAudioRecorder) {
|
||||
guard self.audioRecorder === audioRecorder else {
|
||||
return
|
||||
}
|
||||
updateUI()
|
||||
}
|
||||
|
||||
func audioRecorder(_ audioRecorder: VoiceMessageAudioRecorder, didFailWithError: Error) {
|
||||
guard self.audioRecorder === audioRecorder else {
|
||||
MXLog.error("[VoiceMessageController] audioRecorder failed but it's not the current one.")
|
||||
return
|
||||
}
|
||||
isInLockedMode = false
|
||||
updateUI()
|
||||
|
||||
@@ -214,20 +227,34 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
|
||||
// MARK: - VoiceMessageAudioPlayerDelegate
|
||||
|
||||
func audioPlayerDidStartPlaying(_ audioPlayer: VoiceMessageAudioPlayer) {
|
||||
guard self.audioPlayer === audioPlayer else {
|
||||
return
|
||||
}
|
||||
updateUI()
|
||||
}
|
||||
|
||||
func audioPlayerDidPausePlaying(_ audioPlayer: VoiceMessageAudioPlayer) {
|
||||
guard self.audioPlayer === audioPlayer else {
|
||||
return
|
||||
}
|
||||
updateUI()
|
||||
}
|
||||
|
||||
func audioPlayerDidStopPlaying(_ audioPlayer: VoiceMessageAudioPlayer) {
|
||||
guard self.audioPlayer === audioPlayer else {
|
||||
return
|
||||
}
|
||||
updateUI()
|
||||
}
|
||||
|
||||
func audioPlayerDidFinishPlaying(_ audioPlayer: VoiceMessageAudioPlayer) {
|
||||
guard self.audioPlayer === audioPlayer else {
|
||||
return
|
||||
}
|
||||
audioPlayer.seekToTime(0.0) { [weak self] _ in
|
||||
self?.updateUI()
|
||||
// Reload its content if necessary, otherwise the seek won't work
|
||||
self?.audioPlayer?.reloadContentIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,8 +287,8 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
|
||||
audioRecorder?.stopRecording()
|
||||
|
||||
guard isInLockedMode else {
|
||||
if recordDuration ?? 0 >= Constants.minimumRecordingDuration {
|
||||
sendRecordingAtURL(temporaryFileURL)
|
||||
if recordDuration ?? 0 >= Constants.minimumRecordingDuration, let finalRecordingURL = finalizeRecordingAtURL(temporaryFileURL) {
|
||||
sendRecordingAtURL(finalRecordingURL)
|
||||
} else {
|
||||
cancelRecording()
|
||||
}
|
||||
@@ -277,7 +304,13 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
|
||||
isInLockedMode = false
|
||||
|
||||
audioPlayer?.stop()
|
||||
audioRecorder?.stopRecording()
|
||||
|
||||
// Check if we are recording before stopping the recording, because it will try to pause the audio session and it can be problematic if another player or recorder is running
|
||||
if let audioRecorder, audioRecorder.isRecording {
|
||||
audioRecorder.stopRecording()
|
||||
}
|
||||
// Also, we can release it now, which will prevent the service provider from trying to manage an old audio recorder.
|
||||
audioRecorder = nil
|
||||
|
||||
deleteRecordingAtURL(temporaryFileURL)
|
||||
|
||||
@@ -371,6 +404,23 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
|
||||
}
|
||||
}
|
||||
|
||||
private func finalizeRecordingAtURL(_ url: URL?) -> URL? {
|
||||
guard let url = url, FileManager.default.fileExists(atPath: url.path) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
// We rename the file to something unique, so that we can start a new recording without having to wait for this record to be sent.
|
||||
let newPath = url.deletingPathExtension().path + "-\(UUID().uuidString)"
|
||||
let destinationUrl = URL(fileURLWithPath: newPath).appendingPathExtension(url.pathExtension)
|
||||
do {
|
||||
try FileManager.default.moveItem(at: url, to: destinationUrl)
|
||||
} catch {
|
||||
MXLog.error("[VoiceMessageController] finalizeRecordingAtURL:", context: error)
|
||||
return nil
|
||||
}
|
||||
return destinationUrl
|
||||
}
|
||||
|
||||
private func deleteRecordingAtURL(_ url: URL?) {
|
||||
// Fix: use url.path instead of url.absoluteString when using FileManager otherwise the url seems to be percent encoded and the file is not found.
|
||||
guard let url = url, FileManager.default.fileExists(atPath: url.path) else {
|
||||
|
||||
@@ -48,7 +48,7 @@ import MediaPlayer
|
||||
didSet {
|
||||
// set avatar placeholder for now
|
||||
roomAvatar = AvatarGenerator.generateAvatar(forMatrixItem: currentRoomSummary?.roomId,
|
||||
withDisplayName: currentRoomSummary?.displayname,
|
||||
withDisplayName: currentRoomSummary?.displayName,
|
||||
size: Constants.roomAvatarImageSize.width,
|
||||
andFontSize: Constants.roomAvatarFontSize)
|
||||
|
||||
@@ -191,7 +191,9 @@ import MediaPlayer
|
||||
continue
|
||||
}
|
||||
|
||||
audioRecorder.stopRecording()
|
||||
// We should release the audio session only if we want to pause all services
|
||||
let shouldReleaseAudioSession = (service == nil)
|
||||
audioRecorder.stopRecording(releaseAudioSession: shouldReleaseAudioSession)
|
||||
}
|
||||
|
||||
guard let audioPlayersEnumerator = audioPlayers.objectEnumerator() else {
|
||||
|
||||
@@ -149,6 +149,8 @@ class VoiceMessagePlaybackController: VoiceMessageAudioPlayerDelegate, VoiceMess
|
||||
audioPlayer.seekToTime(0.0) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
self.state = .stopped
|
||||
// Reload its content if necessary, otherwise the seek won't work
|
||||
self.audioPlayer?.reloadContentIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user