jonnyandrew
11 months ago
committed by
GitHub
17 changed files with 369 additions and 40 deletions
@ -0,0 +1,93 @@
@@ -0,0 +1,93 @@
|
||||
/* |
||||
* Copyright (c) 2023 New Vector Ltd |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package io.element.android.features.messages.impl.voicemessages.composer |
||||
|
||||
import io.element.android.features.messages.impl.mediaplayer.MediaPlayer |
||||
import kotlinx.coroutines.flow.Flow |
||||
import kotlinx.coroutines.flow.distinctUntilChanged |
||||
import kotlinx.coroutines.flow.map |
||||
import javax.inject.Inject |
||||
|
||||
/** |
||||
* A media player for the voice message composer. |
||||
* |
||||
* @param mediaPlayer The [MediaPlayer] to use. |
||||
*/ |
||||
class VoiceMessageComposerPlayer @Inject constructor( |
||||
private val mediaPlayer: MediaPlayer, |
||||
) { |
||||
private var lastPlayedMediaPath: String? = null |
||||
private val curPlayingMediaId |
||||
get() = mediaPlayer.state.value.mediaId |
||||
|
||||
val state: Flow<State> = mediaPlayer.state.map { state -> |
||||
if (lastPlayedMediaPath == null || lastPlayedMediaPath != state.mediaId) { |
||||
return@map State.NotPlaying |
||||
} |
||||
|
||||
State( |
||||
isPlaying = state.isPlaying, |
||||
currentPosition = state.currentPosition |
||||
) |
||||
}.distinctUntilChanged() |
||||
|
||||
/** |
||||
* Start playing from the current position. |
||||
* |
||||
* @param mediaPath The path to the media to be played. |
||||
* @param mimeType The mime type of the media file. |
||||
*/ |
||||
fun play(mediaPath: String, mimeType: String) { |
||||
if (mediaPath == curPlayingMediaId) { |
||||
mediaPlayer.play() |
||||
} else { |
||||
lastPlayedMediaPath = mediaPath |
||||
mediaPlayer.acquireControlAndPlay( |
||||
uri = mediaPath, |
||||
mediaId = mediaPath, |
||||
mimeType = mimeType, |
||||
) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Pause playback. |
||||
*/ |
||||
fun pause() { |
||||
if (lastPlayedMediaPath == curPlayingMediaId) { |
||||
mediaPlayer.pause() |
||||
} |
||||
} |
||||
|
||||
data class State( |
||||
/** |
||||
* Whether this player is currently playing. |
||||
*/ |
||||
val isPlaying: Boolean, |
||||
/** |
||||
* The elapsed time of this player in milliseconds. |
||||
*/ |
||||
val currentPosition: Long, |
||||
) { |
||||
companion object { |
||||
val NotPlaying = State( |
||||
isPlaying = false, |
||||
currentPosition = 0L, |
||||
) |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
/* |
||||
* Copyright (c) 2023 New Vector Ltd |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package io.element.android.libraries.textcomposer.model |
||||
|
||||
sealed class VoiceMessagePlayerEvent { |
||||
data object Play: VoiceMessagePlayerEvent() |
||||
data object Pause: VoiceMessagePlayerEvent() |
||||
|
||||
data class Seek( |
||||
val position: Float |
||||
): VoiceMessagePlayerEvent() |
||||
} |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:width="20dp" |
||||
android:height="20dp" |
||||
android:viewportWidth="20" |
||||
android:viewportHeight="20"> |
||||
<path |
||||
android:pathData="M13.25,15.25C12.837,15.25 12.484,15.103 12.191,14.809C11.897,14.516 11.75,14.163 11.75,13.75V6.25C11.75,5.838 11.897,5.484 12.191,5.191C12.484,4.897 12.837,4.75 13.25,4.75H13.75C14.163,4.75 14.516,4.897 14.809,5.191C15.103,5.484 15.25,5.838 15.25,6.25V13.75C15.25,14.163 15.103,14.516 14.809,14.809C14.516,15.103 14.163,15.25 13.75,15.25H13.25ZM6.25,15.25C5.838,15.25 5.484,15.103 5.191,14.809C4.897,14.516 4.75,14.163 4.75,13.75V6.25C4.75,5.838 4.897,5.484 5.191,5.191C5.484,4.897 5.838,4.75 6.25,4.75H6.75C7.162,4.75 7.516,4.897 7.809,5.191C8.103,5.484 8.25,5.838 8.25,6.25V13.75C8.25,14.163 8.103,14.516 7.809,14.809C7.516,15.103 7.162,15.25 6.75,15.25H6.25Z" |
||||
android:fillColor="#656D77"/> |
||||
</vector> |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:width="20dp" |
||||
android:height="20dp" |
||||
android:viewportWidth="20" |
||||
android:viewportHeight="20"> |
||||
<path |
||||
android:pathData="M8.042,14.958C7.75,15.153 7.451,15.167 7.146,15C6.84,14.833 6.688,14.569 6.688,14.208V5.75C6.688,5.389 6.84,5.125 7.146,4.958C7.451,4.792 7.75,4.806 8.042,5L14.688,9.25C14.965,9.417 15.104,9.66 15.104,9.979C15.104,10.299 14.965,10.542 14.688,10.708L8.042,14.958Z" |
||||
android:fillColor="#656D77"/> |
||||
</vector> |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue