diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt index a5e899c672..f068330cb1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt @@ -114,8 +114,13 @@ class AudioMessageHelper @Inject constructor( * When entering in playback mode actually. */ fun pauseRecording() { - voiceRecorder.stopRecord() - stopRecordingAmplitudes() + voiceRecorder.pauseRecord() + pauseRecordingAmplitudes() + } + + fun resumeRecording() { + voiceRecorder.resumeRecord() + resumeRecordingAmplitudes() } fun deleteRecording() { @@ -221,6 +226,14 @@ class AudioMessageHelper @Inject constructor( } } + private fun pauseRecordingAmplitudes() { + amplitudeTicker?.pause() + } + + private fun resumeRecordingAmplitudes() { + amplitudeTicker?.resume() + } + private fun stopRecordingAmplitudes() { amplitudeTicker?.stop() amplitudeTicker = null diff --git a/vector/src/main/java/im/vector/app/features/voice/AbstractVoiceRecorder.kt b/vector/src/main/java/im/vector/app/features/voice/AbstractVoiceRecorder.kt index 5e27aa5bb2..b28d76f176 100644 --- a/vector/src/main/java/im/vector/app/features/voice/AbstractVoiceRecorder.kt +++ b/vector/src/main/java/im/vector/app/features/voice/AbstractVoiceRecorder.kt @@ -32,7 +32,7 @@ abstract class AbstractVoiceRecorder( ) : VoiceRecorder { private val outputDirectory: File by lazy { ensureAudioDirectory(context) } - private var mediaRecorder: MediaRecorder? = null + protected var mediaRecorder: MediaRecorder? = null private var outputFile: File? = null abstract fun setOutputFormat(mediaRecorder: MediaRecorder) @@ -79,8 +79,8 @@ abstract class AbstractVoiceRecorder( } override fun stopRecord() { - // Can throw when the record is less than 1 second. mediaRecorder?.let { + // Can throw when the record is less than 1 second. tryOrNull { it.stop() } it.reset() it.release() diff --git a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorder.kt b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorder.kt index 785fb9b4da..761aad2334 100644 --- a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorder.kt +++ b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorder.kt @@ -34,6 +34,16 @@ interface VoiceRecorder { */ fun startRecord(roomId: String) + /** + * Pause the recording. + */ + fun pauseRecord() + + /** + * Resume the recording. + */ + fun resumeRecord() + /** * Stop the recording. */ diff --git a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderL.kt b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderL.kt index d5395cc849..1460f1a88f 100644 --- a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderL.kt +++ b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderL.kt @@ -23,6 +23,7 @@ import android.media.MediaRecorder import android.media.audiofx.AutomaticGainControl import android.media.audiofx.NoiseSuppressor import android.os.Build +import android.widget.Toast import io.element.android.opusencoder.OggOpusEncoder import io.element.android.opusencoder.configuration.SampleRate import kotlinx.coroutines.CoroutineScope @@ -40,7 +41,7 @@ import kotlin.coroutines.CoroutineContext * VoiceRecorder to be used on Android versions < [Build.VERSION_CODES.Q]. It uses libopus to record ogg files. */ class VoiceRecorderL( - context: Context, + private val context: Context, coroutineContext: CoroutineContext, private val codec: OggOpusEncoder, ) : VoiceRecorder { @@ -112,6 +113,14 @@ class VoiceRecorderL( } } + override fun pauseRecord() { + Toast.makeText(context, "Not implemented for this Android version", Toast.LENGTH_SHORT).show() + } + + override fun resumeRecord() { + Toast.makeText(context, "Not implemented for this Android version", Toast.LENGTH_SHORT).show() + } + override fun stopRecord() { val recorder = this.audioRecorder ?: return recordingJob?.cancel() diff --git a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderQ.kt b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderQ.kt index 5091ddfa3b..1eb850b8f5 100644 --- a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderQ.kt +++ b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderQ.kt @@ -20,12 +20,23 @@ import android.content.Context import android.media.MediaRecorder import android.os.Build import androidx.annotation.RequiresApi +import org.matrix.android.sdk.api.extensions.tryOrNull /** * VoiceRecorder to be used on Android versions >= [Build.VERSION_CODES.Q]. It uses the native OPUS support on Android 10+. */ @RequiresApi(Build.VERSION_CODES.Q) class VoiceRecorderQ(context: Context) : AbstractVoiceRecorder(context, "ogg") { + + override fun pauseRecord() { + // Can throw when the record is less than 1 second. + tryOrNull { mediaRecorder?.pause() } + } + + override fun resumeRecord() { + mediaRecorder?.resume() + } + override fun setOutputFormat(mediaRecorder: MediaRecorder) { // We can directly use OGG here mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.OGG) diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/PauseVoiceBroadcastUseCase.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/PauseVoiceBroadcastUseCase.kt index 8f61284423..6c779b7a50 100644 --- a/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/PauseVoiceBroadcastUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/PauseVoiceBroadcastUseCase.kt @@ -16,6 +16,7 @@ package im.vector.app.features.voicebroadcast.usecase +import im.vector.app.features.home.room.detail.composer.AudioMessageHelper import im.vector.app.features.voicebroadcast.STATE_ROOM_VOICE_BROADCAST_INFO import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState @@ -31,6 +32,7 @@ import javax.inject.Inject class PauseVoiceBroadcastUseCase @Inject constructor( private val session: Session, + private val audioMessageHelper: AudioMessageHelper, ) { suspend fun execute(roomId: String): Result = runCatching { @@ -60,6 +62,10 @@ class PauseVoiceBroadcastUseCase @Inject constructor( ).toContent(), ) - // TODO pause recording audio files + pauseRecording() + } + + private fun pauseRecording() { + audioMessageHelper.pauseRecording() } } diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/ResumeVoiceBroadcastUseCase.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/ResumeVoiceBroadcastUseCase.kt index d0d82b42c3..fbbbc32612 100644 --- a/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/ResumeVoiceBroadcastUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/ResumeVoiceBroadcastUseCase.kt @@ -16,6 +16,7 @@ package im.vector.app.features.voicebroadcast.usecase +import im.vector.app.features.home.room.detail.composer.AudioMessageHelper import im.vector.app.features.voicebroadcast.STATE_ROOM_VOICE_BROADCAST_INFO import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState @@ -31,6 +32,7 @@ import javax.inject.Inject class ResumeVoiceBroadcastUseCase @Inject constructor( private val session: Session, + private val audioMessageHelper: AudioMessageHelper, ) { suspend fun execute(roomId: String): Result = runCatching { @@ -65,6 +67,10 @@ class ResumeVoiceBroadcastUseCase @Inject constructor( ).toContent(), ) - // TODO resume recording audio files + resumeRecording() + } + + private fun resumeRecording() { + audioMessageHelper.resumeRecording() } } diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/StartVoiceBroadcastUseCase.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/StartVoiceBroadcastUseCase.kt index 0b8328cd4b..03dbbed5e4 100644 --- a/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/StartVoiceBroadcastUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/StartVoiceBroadcastUseCase.kt @@ -16,6 +16,7 @@ package im.vector.app.features.voicebroadcast.usecase +import im.vector.app.features.home.room.detail.composer.AudioMessageHelper import im.vector.app.features.voicebroadcast.STATE_ROOM_VOICE_BROADCAST_INFO import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState @@ -30,6 +31,7 @@ import javax.inject.Inject class StartVoiceBroadcastUseCase @Inject constructor( private val session: Session, + private val audioMessageHelper: AudioMessageHelper, ) { suspend fun execute(roomId: String): Result = runCatching { @@ -62,6 +64,10 @@ class StartVoiceBroadcastUseCase @Inject constructor( ).toContent() ) - // TODO start recording audio files + startRecording(room) + } + + private fun startRecording(room: Room) { + audioMessageHelper.startRecording(room.roomId) } } diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/StopVoiceBroadcastUseCase.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/StopVoiceBroadcastUseCase.kt index 8b22193770..ed868fced8 100644 --- a/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/StopVoiceBroadcastUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/StopVoiceBroadcastUseCase.kt @@ -16,6 +16,7 @@ package im.vector.app.features.voicebroadcast.usecase +import im.vector.app.features.home.room.detail.composer.AudioMessageHelper import im.vector.app.features.voicebroadcast.STATE_ROOM_VOICE_BROADCAST_INFO import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState @@ -31,6 +32,7 @@ import javax.inject.Inject class StopVoiceBroadcastUseCase @Inject constructor( private val session: Session, + private val audioMessageHelper: AudioMessageHelper, ) { suspend fun execute(roomId: String): Result = runCatching { @@ -61,6 +63,10 @@ class StopVoiceBroadcastUseCase @Inject constructor( ).toContent(), ) - // TODO stop recording audio files + stopRecording() + } + + private fun stopRecording() { + audioMessageHelper.stopRecording() } }