Skip to content

Commit

Permalink
Fix some voice message issues (#7325, #7217)
Browse files Browse the repository at this point in the history
Fix #7325: prevent setting the audio session to inactive during recording
Fix #7217: ensure that an audio player has its content loaded when it reaches the end to allow seek and replay.
  • Loading branch information
nimau committed Feb 9, 2023
1 parent 0b6aa1f commit 8a1f0b9
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 10 deletions.
11 changes: 10 additions & 1 deletion Riot/Modules/Room/VoiceMessages/VoiceMessageAudioPlayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class VoiceMessageAudioPlayer: NSObject {
return false
}

return (audioPlayer.rate > 0)
return audioPlayer.currentItem != nil && (audioPlayer.rate > 0)
}

var duration: TimeInterval {
Expand Down Expand Up @@ -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()
}
Expand All @@ -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)
Expand Down
17 changes: 10 additions & 7 deletions Riot/Modules/Room/VoiceMessages/VoiceMessageAudioRecorder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
32 changes: 31 additions & 1 deletion Riot/Modules/Room/VoiceMessages/VoiceMessageController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -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()
}
}

Expand Down Expand Up @@ -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)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}

Expand Down
1 change: 1 addition & 0 deletions changelog.d/7217.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A voice message is now replayable.
1 change: 1 addition & 0 deletions changelog.d/7325.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix an issue where a voice message recording was failing.

0 comments on commit 8a1f0b9

Please sign in to comment.