Skip to content

Improved detection of voice broadcast completion during playback #7273

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public class VoiceBroadcastAggregator {
private var voiceBroadcastInfoStartEventContent: VoiceBroadcastInfo!
private var voiceBroadcastSenderId: String!

public private(set) var voiceBroadcastLastChunkSequence: Int = 0

private var referenceEventsListener: Any?

private var events: [MXEvent] = []
Expand Down Expand Up @@ -168,7 +170,10 @@ public class VoiceBroadcastAggregator {
let state = VoiceBroadcastInfoState(rawValue: voiceBroadcastInfo.state) else {
return
}

// For .pause and .stopped, update the last chunk sequence
if [.stopped, .paused].contains(state) {
self.voiceBroadcastLastChunkSequence = voiceBroadcastInfo.lastChunkSequence
}
self.delegate?.voiceBroadcastAggregator(self, didReceiveState: state)
}
}
Expand All @@ -187,6 +192,7 @@ public class VoiceBroadcastAggregator {
}

self.events.removeAll()
self.voiceBroadcastLastChunkSequence = 0

let filteredChunk = response.chunk.filter { event in
event.sender == self.voiceBroadcastSenderId &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,14 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic
private var reloadVoiceBroadcastChunkQueue: Bool = false
private var seekToChunkTime: TimeInterval?

private var lastChunkAddedToPlayer: UInt = 0

private var isPlayingLastChunk: Bool {
// We can't play the last chunk if the brodcast is not stopped
guard state.broadcastState == .stopped else {
return false
}

let chunks = reorderVoiceBroadcastChunks(chunks: Array(voiceBroadcastAggregator.voiceBroadcast.chunks))
guard let chunkDuration = chunks.last?.duration else {
return false
Expand Down Expand Up @@ -168,11 +175,24 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic
private func stopIfVoiceBroadcastOver() {
MXLog.debug("[VoiceBroadcastPlaybackViewModel] stopIfVoiceBroadcastOver")

var shouldStop = false

// Check if the broadcast is over before stopping everything
// If not, the player should not stopped. The view state must be move to buffering
if state.broadcastState == .stopped, isPlayingLastChunk {
if state.broadcastState == .stopped {
// If we known the last chunk sequence, use it to check if we need to stop
// Note: it's possible to be in .stopped state and to still have a last chunk sequence at 0 (old versions or a crash during recording). In this case, we use isPlayingLastChunk as a fallback solution
if voiceBroadcastAggregator.voiceBroadcastLastChunkSequence > 0 {
// we should stop only if we have already added the last chunk to the player
shouldStop = (lastChunkAddedToPlayer == voiceBroadcastAggregator.voiceBroadcastLastChunkSequence)
} else {
shouldStop = isPlayingLastChunk
}
}

if shouldStop {
stop()
} else {
// If not, the player should not stopped. The view state must be move to buffering
state.playbackState = .buffering
}
}
Expand Down Expand Up @@ -200,6 +220,7 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic

private func seek(to seekTime: Float) {
// Flush the chunks queue and the current audio player playlist
lastChunkAddedToPlayer = 0
voiceBroadcastChunkQueue = []
reloadVoiceBroadcastChunkQueue = isProcessingVoiceBroadcastChunk
audioPlayer?.removeAllPlayerItems()
Expand Down Expand Up @@ -294,7 +315,7 @@ class VoiceBroadcastPlaybackViewModel: VoiceBroadcastPlaybackViewModelType, Voic
guard result.eventIdentifier == chunk.attachment.eventId else {
return
}

self.lastChunkAddedToPlayer = max(self.lastChunkAddedToPlayer, chunk.sequence)
self.voiceBroadcastAttachmentCacheManagerLoadResults.append(result)

// Instanciate audioPlayer if needed.
Expand Down Expand Up @@ -436,6 +457,11 @@ extension VoiceBroadcastPlaybackViewModel: VoiceBroadcastAggregatorDelegate {

// Handle the live icon appearance
state.playingState.isLive = isLivePlayback

// Handle the case where the playback state is .buffering and the new broadcast state is .stopped
if didReceiveState == .stopped, self.state.playbackState == .buffering {
stopIfVoiceBroadcastOver()
}
}

func voiceBroadcastAggregatorDidUpdateData(_ aggregator: VoiceBroadcastAggregator) {
Expand Down
1 change: 1 addition & 0 deletions changelog.d/pr-7273.change
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Voice Broadcast: Improved detection of voice broadcast completion during playback.