Merge branch 'langleyd/live_waveform' of https://github.com/vector-im/element-x-android into langleyd/live_waveform
This commit is contained in:
@@ -52,6 +52,7 @@ dependencies {
|
||||
implementation(projects.libraries.permissions.api)
|
||||
implementation(projects.libraries.preferences.api)
|
||||
implementation(projects.libraries.voicerecorder.api)
|
||||
implementation(projects.libraries.mediaplayer.api)
|
||||
implementation(projects.libraries.uiUtils)
|
||||
implementation(projects.features.networkmonitor.api)
|
||||
implementation(projects.services.analytics.api)
|
||||
@@ -83,6 +84,7 @@ dependencies {
|
||||
testImplementation(projects.libraries.preferences.test)
|
||||
testImplementation(projects.libraries.textcomposer.test)
|
||||
testImplementation(projects.libraries.voicerecorder.test)
|
||||
testImplementation(projects.libraries.mediaplayer.test)
|
||||
testImplementation(libs.test.mockk)
|
||||
|
||||
ksp(libs.showkase.processor)
|
||||
|
||||
@@ -31,7 +31,7 @@ import io.element.android.features.messages.impl.attachments.Attachment
|
||||
import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPresenterFactories
|
||||
import io.element.android.features.messages.impl.timeline.di.TimelineItemPresenterFactories
|
||||
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||
import io.element.android.features.messages.impl.mediaplayer.MediaPlayer
|
||||
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package io.element.android.features.messages.impl.voicemessages.composer
|
||||
|
||||
import io.element.android.features.messages.impl.mediaplayer.MediaPlayer
|
||||
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package io.element.android.features.messages.impl.voicemessages.timeline
|
||||
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.features.messages.impl.mediaplayer.MediaPlayer
|
||||
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||
|
||||
@@ -43,7 +43,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
||||
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerPlayer
|
||||
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerPresenter
|
||||
import io.element.android.features.messages.media.FakeLocalMediaFactory
|
||||
import io.element.android.features.messages.mediaplayer.FakeMediaPlayer
|
||||
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
|
||||
import io.element.android.features.messages.textcomposer.TestRichTextEditorStateFactory
|
||||
import io.element.android.features.messages.timeline.components.customreaction.FakeEmojibaseProvider
|
||||
import io.element.android.features.messages.utils.messagesummary.FakeMessageSummaryFormatter
|
||||
|
||||
@@ -30,7 +30,7 @@ import io.element.android.features.messages.impl.voicemessages.composer.VoiceMes
|
||||
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerState
|
||||
import io.element.android.features.messages.impl.voicemessages.VoiceMessageException
|
||||
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerPlayer
|
||||
import io.element.android.features.messages.mediaplayer.FakeMediaPlayer
|
||||
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
|
||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||
import io.element.android.libraries.mediaupload.api.MediaSender
|
||||
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
||||
|
||||
@@ -18,10 +18,10 @@ package io.element.android.features.messages.voicemessages.timeline
|
||||
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth
|
||||
import io.element.android.features.messages.impl.mediaplayer.MediaPlayer
|
||||
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
||||
import io.element.android.features.messages.impl.voicemessages.timeline.DefaultVoiceMessagePlayer
|
||||
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageMediaRepo
|
||||
import io.element.android.features.messages.mediaplayer.FakeMediaPlayer
|
||||
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||
|
||||
@@ -27,7 +27,7 @@ import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMes
|
||||
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageMediaRepo
|
||||
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessagePresenter
|
||||
import io.element.android.features.messages.impl.voicemessages.timeline.VoiceMessageState
|
||||
import io.element.android.features.messages.mediaplayer.FakeMediaPlayer
|
||||
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
|
||||
32
libraries/mediaplayer/api/build.gradle.kts
Normal file
32
libraries/mediaplayer/api/build.gradle.kts
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
plugins {
|
||||
id("io.element.android-library")
|
||||
alias(libs.plugins.anvil)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "io.element.android.libraries.mediaplayer.api"
|
||||
}
|
||||
|
||||
anvil {
|
||||
generateDaggerFactories.set(true)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.libraries.matrix.api)
|
||||
implementation(libs.coroutines.core)
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.mediaplayer.api
|
||||
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
/**
|
||||
* A media player for Element X.
|
||||
*/
|
||||
interface MediaPlayer : AutoCloseable {
|
||||
|
||||
/**
|
||||
* The current state of the player.
|
||||
*/
|
||||
val state: StateFlow<State>
|
||||
|
||||
/**
|
||||
* Acquires control of the player and starts playing the given media.
|
||||
*/
|
||||
fun acquireControlAndPlay(
|
||||
uri: String,
|
||||
mediaId: String,
|
||||
mimeType: String,
|
||||
)
|
||||
|
||||
/**
|
||||
* Plays the current media.
|
||||
*/
|
||||
fun play()
|
||||
|
||||
/**
|
||||
* Pauses the current media.
|
||||
*/
|
||||
fun pause()
|
||||
|
||||
/**
|
||||
* Seeks the current media to the given position.
|
||||
*/
|
||||
fun seekTo(positionMs: Long)
|
||||
|
||||
/**
|
||||
* Releases any resources associated with this player.
|
||||
*/
|
||||
override fun close()
|
||||
|
||||
data class State(
|
||||
/**
|
||||
* Whether the player is currently playing.
|
||||
*/
|
||||
val isPlaying: Boolean,
|
||||
/**
|
||||
* The id of the media which is currently playing.
|
||||
*
|
||||
* NB: This is usually the string representation of the [EventId] of the event
|
||||
* which contains the media.
|
||||
*/
|
||||
val mediaId: String?,
|
||||
/**
|
||||
* The current position of the player.
|
||||
*/
|
||||
val currentPosition: Long,
|
||||
)
|
||||
}
|
||||
45
libraries/mediaplayer/impl/build.gradle.kts
Normal file
45
libraries/mediaplayer/impl/build.gradle.kts
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
plugins {
|
||||
id("io.element.android-library")
|
||||
alias(libs.plugins.anvil)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "io.element.android.libraries.mediaplayer.impl"
|
||||
}
|
||||
|
||||
anvil {
|
||||
generateDaggerFactories.set(true)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(projects.libraries.mediaplayer.api)
|
||||
implementation(libs.androidx.media3.exoplayer)
|
||||
|
||||
implementation(libs.dagger)
|
||||
implementation(projects.libraries.di)
|
||||
|
||||
implementation(libs.coroutines.core)
|
||||
|
||||
testImplementation(projects.tests.testutils)
|
||||
testImplementation(libs.test.junit)
|
||||
testImplementation(libs.test.truth)
|
||||
testImplementation(libs.test.mockk)
|
||||
testImplementation(libs.test.turbine)
|
||||
testImplementation(libs.coroutines.core)
|
||||
testImplementation(libs.coroutines.test)
|
||||
}
|
||||
@@ -14,14 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.features.messages.impl.mediaplayer
|
||||
package io.element.android.libraries.mediaplayer.impl
|
||||
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.Player
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.di.SingleIn
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
@@ -33,64 +33,6 @@ import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* A media player for Element X.
|
||||
*/
|
||||
interface MediaPlayer : AutoCloseable {
|
||||
|
||||
/**
|
||||
* The current state of the player.
|
||||
*/
|
||||
val state: StateFlow<State>
|
||||
|
||||
/**
|
||||
* Acquires control of the player and starts playing the given media.
|
||||
*/
|
||||
fun acquireControlAndPlay(
|
||||
uri: String,
|
||||
mediaId: String,
|
||||
mimeType: String,
|
||||
)
|
||||
|
||||
/**
|
||||
* Plays the current media.
|
||||
*/
|
||||
fun play()
|
||||
|
||||
/**
|
||||
* Pauses the current media.
|
||||
*/
|
||||
fun pause()
|
||||
|
||||
/**
|
||||
* Seeks the current media to the given position.
|
||||
*/
|
||||
fun seekTo(positionMs: Long)
|
||||
|
||||
/**
|
||||
* Releases any resources associated with this player.
|
||||
*/
|
||||
override fun close()
|
||||
|
||||
data class State(
|
||||
/**
|
||||
* Whether the player is currently playing.
|
||||
*/
|
||||
val isPlaying: Boolean,
|
||||
/**
|
||||
* The id of the media which is currently playing.
|
||||
*
|
||||
* NB: This is usually the string representation of the [EventId] of the event
|
||||
* which contains the media.
|
||||
*/
|
||||
val mediaId: String?,
|
||||
/**
|
||||
* The current position of the player.
|
||||
*/
|
||||
val currentPosition: Long,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of [MediaPlayer] backed by a [SimplePlayer].
|
||||
*/
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.features.messages.impl.mediaplayer
|
||||
package io.element.android.libraries.mediaplayer.impl
|
||||
|
||||
import android.content.Context
|
||||
import androidx.media3.common.MediaItem
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.mediaplayer.impl
|
||||
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
class MediaPlayerImplTest {
|
||||
@Test
|
||||
fun `default test`() = runTest {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
31
libraries/mediaplayer/test/build.gradle.kts
Normal file
31
libraries/mediaplayer/test/build.gradle.kts
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id("io.element.android-library")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "io.element.android.libraries.mediaplayer.test"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(projects.libraries.mediaplayer.api)
|
||||
implementation(projects.tests.testutils)
|
||||
|
||||
implementation(libs.coroutines.test)
|
||||
implementation(libs.test.truth)
|
||||
}
|
||||
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.features.messages.mediaplayer
|
||||
package io.element.android.libraries.mediaplayer.test
|
||||
|
||||
import io.element.android.features.messages.impl.mediaplayer.MediaPlayer
|
||||
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
@@ -28,6 +28,6 @@ dependencies {
|
||||
implementation(libs.kotlin.gradle.plugin)
|
||||
implementation(platform(libs.google.firebase.bom))
|
||||
// FIXME: using the bom ^, it should not be necessary to provide the version v...
|
||||
implementation("com.google.firebase:firebase-appdistribution-gradle:4.0.0")
|
||||
implementation("com.google.firebase:firebase-appdistribution-gradle:4.0.1")
|
||||
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ fun DependencyHandlerScope.allLibrariesImpl() {
|
||||
implementation(project(":libraries:textcomposer:impl"))
|
||||
implementation(project(":libraries:cryptography:impl"))
|
||||
implementation(project(":libraries:voicerecorder:impl"))
|
||||
implementation(project(":libraries:mediaplayer:impl"))
|
||||
}
|
||||
|
||||
fun DependencyHandlerScope.allServicesImpl() {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user