-
Notifications
You must be signed in to change notification settings - Fork 859
Voice Broadcast - Handle event deletion when listening or recording #7629
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
Florian14
merged 12 commits into
develop
from
feature/fre/voice_broadcast_handle_event_deletion
Nov 29, 2022
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
2d60e49
Handle redaction when observing voice broadcast state changes
f436de1
Handle voice broadcast deletion on listener side
763b60e
Update voice broadcast recorder according to the most recent voice br…
3ebcd8c
changelog
023326a
Do not wait for state event feedback for pause/stop actions on the re…
a2dee21
Fix bad condition
d092c83
Fix wrong sequence number in stopped state event content
9dba6d7
Fix issue on live playback detection
4427156
Restore trailing comma
aa53105
improve flow stream
620bebc
Rewrite condition for better clarity
9840731
Add todo for missing unit test
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Voice Broadcast - Handle redaction of the state events on the listener and recorder sides |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,8 +20,17 @@ import android.content.Context | |
| import android.media.MediaRecorder | ||
| import android.os.Build | ||
| import androidx.annotation.RequiresApi | ||
| import im.vector.app.core.di.ActiveSessionHolder | ||
| import im.vector.app.features.session.coroutineScope | ||
| import im.vector.app.features.voice.AbstractVoiceRecorderQ | ||
| import im.vector.app.features.voicebroadcast.model.VoiceBroadcast | ||
| import im.vector.app.features.voicebroadcast.model.VoiceBroadcastEvent | ||
| import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState | ||
| import im.vector.app.features.voicebroadcast.usecase.GetMostRecentVoiceBroadcastStateEventUseCase | ||
| import im.vector.lib.core.utils.timer.CountUpTimer | ||
| import kotlinx.coroutines.Job | ||
| import kotlinx.coroutines.flow.launchIn | ||
| import kotlinx.coroutines.flow.onEach | ||
| import org.matrix.android.sdk.api.extensions.tryOrNull | ||
| import org.matrix.android.sdk.api.session.content.ContentAttachmentData | ||
| import java.util.concurrent.CopyOnWriteArrayList | ||
|
|
@@ -30,10 +39,17 @@ import java.util.concurrent.TimeUnit | |
| @RequiresApi(Build.VERSION_CODES.Q) | ||
| class VoiceBroadcastRecorderQ( | ||
| context: Context, | ||
| private val sessionHolder: ActiveSessionHolder, | ||
| private val getVoiceBroadcastEventUseCase: GetMostRecentVoiceBroadcastStateEventUseCase | ||
| ) : AbstractVoiceRecorderQ(context), VoiceBroadcastRecorder { | ||
|
|
||
| private val session get() = sessionHolder.getActiveSession() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have you considered it may throw an exception when getting the session variable? |
||
| private val sessionScope get() = session.coroutineScope | ||
|
|
||
| private var voiceBroadcastStateObserver: Job? = null | ||
|
|
||
| private var maxFileSize = 0L // zero or negative for no limit | ||
| private var currentRoomId: String? = null | ||
| private var currentVoiceBroadcast: VoiceBroadcast? = null | ||
| private var currentMaxLength: Int = 0 | ||
|
|
||
| override var currentSequence = 0 | ||
|
|
@@ -68,17 +84,20 @@ class VoiceBroadcastRecorderQ( | |
| } | ||
| } | ||
|
|
||
| override fun startRecord(roomId: String, chunkLength: Int, maxLength: Int) { | ||
| currentRoomId = roomId | ||
| override fun startRecordVoiceBroadcast(voiceBroadcast: VoiceBroadcast, chunkLength: Int, maxLength: Int) { | ||
| // Stop recording previous voice broadcast if any | ||
| if (recordingState != VoiceBroadcastRecorder.State.Idle) stopRecord() | ||
|
|
||
| currentVoiceBroadcast = voiceBroadcast | ||
| maxFileSize = (chunkLength * audioEncodingBitRate / 8).toLong() | ||
| currentMaxLength = maxLength | ||
| currentSequence = 1 | ||
| startRecord(roomId) | ||
| recordingState = VoiceBroadcastRecorder.State.Recording | ||
| recordingTicker.start() | ||
|
|
||
| observeVoiceBroadcastStateEvent(voiceBroadcast) | ||
| } | ||
|
|
||
| override fun pauseRecord() { | ||
| if (recordingState != VoiceBroadcastRecorder.State.Recording) return | ||
| tryOrNull { mediaRecorder?.stop() } | ||
| mediaRecorder?.reset() | ||
| recordingState = VoiceBroadcastRecorder.State.Paused | ||
|
|
@@ -87,8 +106,9 @@ class VoiceBroadcastRecorderQ( | |
| } | ||
|
|
||
| override fun resumeRecord() { | ||
| if (recordingState != VoiceBroadcastRecorder.State.Paused) return | ||
| currentSequence++ | ||
| currentRoomId?.let { startRecord(it) } | ||
| currentVoiceBroadcast?.let { startRecord(it.roomId) } | ||
| recordingState = VoiceBroadcastRecorder.State.Recording | ||
| recordingTicker.resume() | ||
| } | ||
|
|
@@ -104,11 +124,15 @@ class VoiceBroadcastRecorderQ( | |
| // Remove listeners | ||
| listeners.clear() | ||
|
|
||
| // Do not observe anymore voice broadcast changes | ||
| voiceBroadcastStateObserver?.cancel() | ||
| voiceBroadcastStateObserver = null | ||
|
|
||
| // Reset data | ||
| currentSequence = 0 | ||
| currentMaxLength = 0 | ||
| currentRemainingTime = null | ||
| currentRoomId = null | ||
| currentVoiceBroadcast = null | ||
| } | ||
|
|
||
| override fun release() { | ||
|
|
@@ -126,6 +150,26 @@ class VoiceBroadcastRecorderQ( | |
| listeners.remove(listener) | ||
| } | ||
|
|
||
| private fun observeVoiceBroadcastStateEvent(voiceBroadcast: VoiceBroadcast) { | ||
| voiceBroadcastStateObserver = getVoiceBroadcastEventUseCase.execute(voiceBroadcast) | ||
| .onEach { onVoiceBroadcastStateEventUpdated(voiceBroadcast, it.getOrNull()) } | ||
| .launchIn(sessionScope) | ||
| } | ||
|
|
||
| private fun onVoiceBroadcastStateEventUpdated(voiceBroadcast: VoiceBroadcast, event: VoiceBroadcastEvent?) { | ||
| when (event?.content?.voiceBroadcastState) { | ||
| VoiceBroadcastState.STARTED -> { | ||
| startRecord(voiceBroadcast.roomId) | ||
| recordingState = VoiceBroadcastRecorder.State.Recording | ||
| recordingTicker.start() | ||
| } | ||
| VoiceBroadcastState.PAUSED -> pauseRecord() | ||
| VoiceBroadcastState.RESUMED -> resumeRecord() | ||
| VoiceBroadcastState.STOPPED, | ||
| null -> stopRecord() | ||
| } | ||
| } | ||
|
|
||
| private fun onMaxFileSizeApproaching(roomId: String) { | ||
| setNextOutputFile(roomId) | ||
| } | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think we need to add
VoiceBroadcastin the name of the method? I personnally think this is enough withstartRecordsince first parameter is aVoiceBroadcast.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My problem is that I want to distinguish this method from the startRecord which is inherited from VoiceRecorder to avoid confusion. Ideally, I would like to only expose this one to the outside and change the visibility of the other method to "protected", but afaik I can do it programmatically but this is a bit ugly imo. Wdyt @mnaturel?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. I didn't see the method in the
VoiceRecorderInterface. Let's keep it like this then.