Merge pull request #7357 from vector-im/nimau/7325_voicemessage_recording_issue

Fix some voice message issues (#7325, #7217)
This commit is contained in:
Nicolas Mauri
2023-02-09 13:41:49 +01:00
committed by GitHub
7 changed files with 58 additions and 10 deletions
@@ -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 {
@@ -199,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()
@@ -217,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()
}
}
@@ -280,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)
@@ -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 {
@@ -144,6 +144,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()
}
}
+1
View File
@@ -0,0 +1 @@
A voice message is now replayable.
+1
View File
@@ -0,0 +1 @@
Fix an issue where a voice message recording was failing.