mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-20 08:32:53 +02:00
#4094 - Added voice message attachment decryption, transcoding and sampling caching layer.
This commit is contained in:
@@ -35,7 +35,9 @@ class VoiceMessagePlaybackController: VoiceMessageAudioPlayerDelegate, VoiceMess
|
||||
dateFormatter.dateFormat = Constants.elapsedTimeFormat
|
||||
return dateFormatter
|
||||
}()
|
||||
|
||||
|
||||
private let cacheManager: VoiceMessageAttachmentCacheManager
|
||||
|
||||
private let audioPlayer: VoiceMessageAudioPlayer
|
||||
private var displayLink: CADisplayLink!
|
||||
private var samples: [Float] = []
|
||||
@@ -49,7 +51,10 @@ class VoiceMessagePlaybackController: VoiceMessageAudioPlayerDelegate, VoiceMess
|
||||
|
||||
let playbackView: VoiceMessagePlaybackView
|
||||
|
||||
init(mediaServiceProvider: VoiceMessageMediaServiceProvider) {
|
||||
init(mediaServiceProvider: VoiceMessageMediaServiceProvider,
|
||||
cacheManager: VoiceMessageAttachmentCacheManager) {
|
||||
self.cacheManager = cacheManager
|
||||
|
||||
playbackView = VoiceMessagePlaybackView.loadFromNib()
|
||||
audioPlayer = mediaServiceProvider.audioPlayer()
|
||||
|
||||
@@ -62,22 +67,12 @@ class VoiceMessagePlaybackController: VoiceMessageAudioPlayerDelegate, VoiceMess
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(updateTheme), name: .themeServiceDidChangeTheme, object: nil)
|
||||
updateTheme()
|
||||
updateUI()
|
||||
}
|
||||
|
||||
|
||||
var attachment: MXKAttachment? {
|
||||
didSet {
|
||||
if oldValue?.contentURL == attachment?.contentURL &&
|
||||
oldValue?.eventSentState == attachment?.eventSentState {
|
||||
return
|
||||
}
|
||||
|
||||
switch attachment?.eventSentState {
|
||||
case MXEventSentStateFailed:
|
||||
state = .error
|
||||
default:
|
||||
state = .stopped
|
||||
loadAttachmentData()
|
||||
}
|
||||
loadAttachmentData()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,79 +138,26 @@ class VoiceMessagePlaybackController: VoiceMessageAudioPlayerDelegate, VoiceMess
|
||||
|
||||
playbackView.configureWithDetails(details)
|
||||
}
|
||||
|
||||
|
||||
private func loadAttachmentData() {
|
||||
guard let attachment = attachment else {
|
||||
return
|
||||
}
|
||||
|
||||
if attachment.isEncrypted {
|
||||
attachment.decrypt(toTempFile: { [weak self] filePath in
|
||||
self?.convertAndLoadFileAtPath(filePath)
|
||||
}, failure: { [weak self] error in
|
||||
// A nil error in this case is a cancellation on the MXMediaLoader
|
||||
if let error = error {
|
||||
MXLog.error("Failed decrypting attachment with error: \(String(describing: error))")
|
||||
self?.state = .error
|
||||
}
|
||||
})
|
||||
} else {
|
||||
attachment.prepare({ [weak self] in
|
||||
self?.convertAndLoadFileAtPath(attachment.cacheFilePath)
|
||||
}, failure: { [weak self] error in
|
||||
// A nil error in this case is a cancellation on the MXMediaLoader
|
||||
if let error = error {
|
||||
MXLog.error("Failed preparing attachment with error: \(String(describing: error))")
|
||||
self?.state = .error
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private func convertAndLoadFileAtPath(_ path: String?) {
|
||||
guard let filePath = path else {
|
||||
return
|
||||
}
|
||||
|
||||
let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
|
||||
let newURL = temporaryDirectoryURL.appendingPathComponent(ProcessInfo().globallyUniqueString).appendingPathExtension("m4a")
|
||||
|
||||
VoiceMessageAudioConverter.convertToMPEG4AAC(sourceURL: URL(fileURLWithPath: filePath), destinationURL: newURL) { [weak self] result in
|
||||
switch result {
|
||||
case .success:
|
||||
self?.loadFileAtURL(newURL)
|
||||
case .failure(let error):
|
||||
self?.state = .error
|
||||
MXLog.error("Failed failed decoding audio message with: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func loadFileAtURL(_ url: URL) {
|
||||
|
||||
audioPlayer.loadContentFromURL(url)
|
||||
|
||||
let requiredNumberOfSamples = playbackView.getRequiredNumberOfSamples()
|
||||
|
||||
if requiredNumberOfSamples == 0 {
|
||||
return
|
||||
cacheManager.loadAttachment(attachment, numberOfSamples: requiredNumberOfSamples) { result in
|
||||
switch result {
|
||||
case .success(let result):
|
||||
self.audioPlayer.loadContentFromURL(result.0)
|
||||
self.samples = result.1
|
||||
self.updateUI()
|
||||
case .failure:
|
||||
self.state = .error
|
||||
}
|
||||
}
|
||||
|
||||
let analyser = WaveformAnalyzer(audioAssetURL: url)
|
||||
analyser?.samples(count: requiredNumberOfSamples, completionHandler: { [weak self] samples in
|
||||
guard let samples = samples else {
|
||||
self?.state = .error
|
||||
return
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self?.samples = samples
|
||||
self?.updateUI()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@objc private func updateTheme() {
|
||||
playbackView.update(theme: ThemeService.shared().theme)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user