diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index a2ca27bd7..f21972c48 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -631,7 +631,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; self.updateRoomReadMarker = NO; isAppeared = NO; - [VoiceMessageMediaServiceProvider.sharedProvider stopAllServices]; + [VoiceMessageMediaServiceProvider.sharedProvider pauseAllServices]; } - (void)viewDidAppear:(BOOL)animated diff --git a/Riot/Modules/Room/VoiceMessages/VoiceMessageMediaServiceProvider.swift b/Riot/Modules/Room/VoiceMessages/VoiceMessageMediaServiceProvider.swift index 1cca80dd3..3037c67d0 100644 --- a/Riot/Modules/Room/VoiceMessages/VoiceMessageMediaServiceProvider.swift +++ b/Riot/Modules/Room/VoiceMessages/VoiceMessageMediaServiceProvider.swift @@ -31,7 +31,13 @@ import MediaPlayer private var displayLink: CADisplayLink! - // Retain currently playing audio player so it doesn't stop playing on timeline cell reuse + + + // Retain active audio players(playing or paused) so it doesn't stop playing on timeline cell reuse + // and we can pause/resume players on switching rooms. + private var activeAudioPlayers: Set + + // Keep reference to currently playing player for remote control. private var currentlyPlayingAudioPlayer: VoiceMessageAudioPlayer? @objc public static let sharedProvider = VoiceMessageMediaServiceProvider() @@ -87,7 +93,7 @@ import MediaPlayer private override init() { audioPlayers = NSMapTable(valueOptions: .weakMemory) audioRecorders = NSHashTable(options: .weakMemory) - + activeAudioPlayers = Set() super.init() displayLink = CADisplayLink(target: WeakTarget(self, selector: #selector(handleDisplayLinkTick)), selector: WeakTarget.triggerSelector) @@ -113,16 +119,17 @@ import MediaPlayer return audioRecorder } - @objc func stopAllServices() { - stopAllServicesExcept(nil) + @objc func pauseAllServices() { + pauseAllServicesExcept(nil) } // MARK: - VoiceMessageAudioPlayerDelegate func audioPlayerDidStartPlaying(_ audioPlayer: VoiceMessageAudioPlayer) { currentlyPlayingAudioPlayer = audioPlayer + activeAudioPlayers.insert(audioPlayer) setUpRemoteCommandCenter() - stopAllServicesExcept(audioPlayer) + pauseAllServicesExcept(audioPlayer) } func audioPlayerDidStopPlaying(_ audioPlayer: VoiceMessageAudioPlayer) { @@ -130,6 +137,7 @@ import MediaPlayer currentlyPlayingAudioPlayer = nil tearDownRemoteCommandCenter() } + activeAudioPlayers.remove(audioPlayer) } func audioPlayerDidFinishPlaying(_ audioPlayer: VoiceMessageAudioPlayer) { @@ -137,17 +145,18 @@ import MediaPlayer currentlyPlayingAudioPlayer = nil tearDownRemoteCommandCenter() } + activeAudioPlayers.remove(audioPlayer) } // MARK: - VoiceMessageAudioRecorderDelegate func audioRecorderDidStartRecording(_ audioRecorder: VoiceMessageAudioRecorder) { - stopAllServicesExcept(audioRecorder) + pauseAllServicesExcept(audioRecorder) } // MARK: - Private - private func stopAllServicesExcept(_ service: AnyObject?) { + private func pauseAllServicesExcept(_ service: AnyObject?) { for audioRecorder in audioRecorders.allObjects { if audioRecorder === service { continue @@ -165,8 +174,7 @@ import MediaPlayer continue } - audioPlayer.stop() - audioPlayer.unloadContent() + audioPlayer.pause() } } diff --git a/changelog.d/47773.change b/changelog.d/47773.change new file mode 100644 index 000000000..826cb00bd --- /dev/null +++ b/changelog.d/47773.change @@ -0,0 +1 @@ +Voice Messages: Pause playback when changing rooms while retaining the playback position when re-entering.