#4545 - Switch back to using multiple audio player instances, allow pausing when starting a new player.

This commit is contained in:
Stefan Ceriu
2021-07-12 15:30:48 +03:00
parent 4224609839
commit 6f9cfaa0b5
3 changed files with 87 additions and 72 deletions
@@ -44,6 +44,9 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
private let _voiceMessageToolbarView: VoiceMessageToolbarView
private var displayLink: CADisplayLink!
private var audioRecorder: VoiceMessageAudioRecorder?
private var audioPlayer: VoiceMessageAudioPlayer?
private var waveformAnalyser: WaveformAnalyzer?
private var audioSamples: [Float] = []
@@ -53,7 +56,7 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
@objc public weak var delegate: VoiceMessageControllerDelegate?
@objc public var isRecordingAudio: Bool {
return mediaServiceProvider.audioRecorder.isRecording || isInLockedMode
return audioRecorder?.isRecording ?? false || isInLockedMode
}
@objc public var voiceMessageToolbarView: UIView {
@@ -101,8 +104,9 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
let temporaryFileURL = temporaryDirectoryURL.appendingPathComponent(ProcessInfo().globallyUniqueString).appendingPathExtension("m4a")
mediaServiceProvider.audioRecorder.registerDelegate(self)
mediaServiceProvider.audioRecorder.recordWithOuputURL(temporaryFileURL)
audioRecorder = mediaServiceProvider.audioRecorder()
audioRecorder?.registerDelegate(self)
audioRecorder?.recordWithOuputURL(temporaryFileURL)
}
func voiceMessageToolbarViewDidRequestRecordingFinish(_ toolbarView: VoiceMessageToolbarView) {
@@ -111,8 +115,8 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
func voiceMessageToolbarViewDidRequestRecordingCancel(_ toolbarView: VoiceMessageToolbarView) {
isInLockedMode = false
mediaServiceProvider.audioRecorder.stopRecording()
deleteRecordingAtURL(mediaServiceProvider.audioRecorder.url)
audioRecorder?.stopRecording()
deleteRecordingAtURL(audioRecorder?.url)
UINotificationFeedbackGenerator().notificationOccurred(.error)
updateUI()
}
@@ -123,21 +127,21 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
}
func voiceMessageToolbarViewDidRequestPlaybackToggle(_ toolbarView: VoiceMessageToolbarView) {
if mediaServiceProvider.audioPlayer.isPlaying {
mediaServiceProvider.audioPlayer.pause()
if audioPlayer?.isPlaying ?? false {
audioPlayer?.pause()
} else {
mediaServiceProvider.audioPlayer.play()
audioPlayer?.play()
}
}
func voiceMessageToolbarViewDidRequestSend(_ toolbarView: VoiceMessageToolbarView) {
guard let url = mediaServiceProvider.audioRecorder.url else {
guard let url = audioRecorder?.url else {
MXLog.error("Invalid audio recording URL")
return
}
mediaServiceProvider.audioPlayer.stop()
mediaServiceProvider.audioRecorder.stopRecording()
audioPlayer?.stop()
audioRecorder?.stopRecording()
sendRecordingAtURL(url)
@@ -191,23 +195,25 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
// MARK: - Private
private func finishRecording() {
let recordDuration = mediaServiceProvider.audioRecorder.currentTime
mediaServiceProvider.audioRecorder.stopRecording()
let recordDuration = audioRecorder?.currentTime
audioRecorder?.stopRecording()
guard let url = mediaServiceProvider.audioRecorder.url else {
guard let url = audioRecorder?.url else {
MXLog.error("Invalid audio recording URL")
return
}
guard isInLockedMode else {
if recordDuration >= Constants.minimumRecordingDuration {
if recordDuration ?? 0 >= Constants.minimumRecordingDuration {
sendRecordingAtURL(url)
}
return
}
mediaServiceProvider.audioPlayer.registerDelegate(self)
mediaServiceProvider.audioPlayer.loadContentFromURL(url)
audioPlayer = mediaServiceProvider.audioPlayer()
audioPlayer?.registerDelegate(self)
audioPlayer?.loadContentFromURL(url)
audioSamples = []
updateUI()
@@ -255,7 +261,7 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
private func updateUI() {
let shouldUpdateFromAudioPlayer = isInLockedMode && !mediaServiceProvider.audioRecorder.isRecording
let shouldUpdateFromAudioPlayer = isInLockedMode && !(audioRecorder?.isRecording ?? false)
if shouldUpdateFromAudioPlayer {
updateUIFromAudioPlayer()
@@ -265,7 +271,7 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
}
private func updateUIFromAudioRecorder() {
let isRecording = mediaServiceProvider.audioRecorder.isRecording
let isRecording = audioRecorder?.isRecording ?? false
displayLink.isPaused = !isRecording
@@ -275,11 +281,11 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
padSamplesArrayToSize(requiredNumberOfSamples)
}
let sample = mediaServiceProvider.audioRecorder.averagePowerForChannelNumber(0)
let sample = audioRecorder?.averagePowerForChannelNumber(0) ?? 0.0
audioSamples.insert(sample, at: 0)
audioSamples.removeLast()
let currentTime = mediaServiceProvider.audioRecorder.currentTime
let currentTime = audioRecorder?.currentTime ?? 0.0
if currentTime >= Constants.maximumAudioRecordingDuration {
finishRecording()
@@ -311,12 +317,16 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
}
private func updateUIFromAudioPlayer() {
guard let url = mediaServiceProvider.audioPlayer.url else {
guard let audioPlayer = audioPlayer else {
return
}
guard let url = audioPlayer.url else {
MXLog.error("Invalid audio player url.")
return
}
displayLink.isPaused = !mediaServiceProvider.audioPlayer.isPlaying
displayLink.isPaused = !audioPlayer.isPlaying
let requiredNumberOfSamples = _voiceMessageToolbarView.getRequiredNumberOfSamples()
if audioSamples.count != requiredNumberOfSamples && requiredNumberOfSamples > 0 {
@@ -337,11 +347,11 @@ public class VoiceMessageController: NSObject, VoiceMessageToolbarViewDelegate,
}
var details = VoiceMessageToolbarViewDetails()
details.state = (mediaServiceProvider.audioRecorder.isRecording ? (isInLockedMode ? .lockedModeRecord : .record) : (isInLockedMode ? .lockedModePlayback : .idle))
details.elapsedTime = VoiceMessageController.timeFormatter.string(from: Date(timeIntervalSinceReferenceDate: (mediaServiceProvider.audioPlayer.isPlaying ? mediaServiceProvider.audioPlayer.currentTime : mediaServiceProvider.audioPlayer.duration)))
details.state = (audioRecorder?.isRecording ?? false ? (isInLockedMode ? .lockedModeRecord : .record) : (isInLockedMode ? .lockedModePlayback : .idle))
details.elapsedTime = VoiceMessageController.timeFormatter.string(from: Date(timeIntervalSinceReferenceDate: (audioPlayer.isPlaying ? audioPlayer.currentTime : audioPlayer.duration)))
details.audioSamples = audioSamples
details.isPlaying = mediaServiceProvider.audioPlayer.isPlaying
details.progress = (mediaServiceProvider.audioPlayer.duration > 0.0 ? mediaServiceProvider.audioPlayer.currentTime / mediaServiceProvider.audioPlayer.duration : 0.0)
details.isPlaying = audioPlayer.isPlaying
details.progress = (audioPlayer.duration > 0.0 ? audioPlayer.currentTime / audioPlayer.duration : 0.0)
_voiceMessageToolbarView.configureWithDetails(details)
}