diff --git a/video/app/src/main/AndroidManifest.xml b/video/app/src/main/AndroidManifest.xml
index ad55630ca3..cde6d6b0b6 100644
--- a/video/app/src/main/AndroidManifest.xml
+++ b/video/app/src/main/AndroidManifest.xml
@@ -1,5 +1,4 @@
-
-
@@ -16,7 +15,6 @@
@@ -24,6 +22,14 @@
+
+
\ No newline at end of file
diff --git a/video/app/src/main/java/org/thoughtcrime/video/app/MainActivity.kt b/video/app/src/main/java/org/thoughtcrime/video/app/MainActivity.kt
index 267299b1f7..909d767860 100644
--- a/video/app/src/main/java/org/thoughtcrime/video/app/MainActivity.kt
+++ b/video/app/src/main/java/org/thoughtcrime/video/app/MainActivity.kt
@@ -5,43 +5,36 @@
package org.thoughtcrime.video.app
+import android.content.Intent
+import android.content.pm.ActivityInfo
+import android.content.pm.PackageManager
+import android.content.pm.PackageManager.NameNotFoundException
import android.os.Bundle
import android.util.Log
-import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
-import androidx.activity.result.PickVisualMediaRequest
-import androidx.activity.result.contract.ActivityResultContracts
-import androidx.activity.viewModels
-import androidx.annotation.OptIn
+import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.viewinterop.AndroidView
-import androidx.media3.common.util.UnstableApi
-import androidx.media3.exoplayer.ExoPlayer
-import androidx.media3.exoplayer.source.MediaSource
-import androidx.media3.ui.PlayerView
+import org.thoughtcrime.video.app.playback.PlaybackTestActivity
+import org.thoughtcrime.video.app.transcode.TranscodeTestActivity
+import org.thoughtcrime.video.app.ui.composables.LabeledButton
import org.thoughtcrime.video.app.ui.theme.SignalTheme
+
/**
* Main activity for this sample app.
*/
-class MainActivity : ComponentActivity() {
- private val viewModel: MainScreenViewModel by viewModels()
- private lateinit var exoPlayer: ExoPlayer
+class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- viewModel.initialize(this)
- exoPlayer = ExoPlayer.Builder(this).build()
+ val startPlaybackScreen = Intent(this, PlaybackTestActivity::class.java)
+ val startTranscodeScreen = Intent(this, TranscodeTestActivity::class.java)
setContent {
SignalTheme {
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
@@ -49,70 +42,11 @@ class MainActivity : ComponentActivity() {
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
- val videoUri = viewModel.selectedVideo
- if (videoUri == null) {
- LabeledButton("Select Video") { pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.VideoOnly)) }
- } else {
- LabeledButton("Play Video") { viewModel.updateMediaSource(this@MainActivity) }
- LabeledButton("Play Video with slow download") { viewModel.updateMediaSourceTrickle(this@MainActivity) }
- ExoVideoView(source = viewModel.mediaSource, exoPlayer = exoPlayer)
- }
+ LabeledButton("Test Playback") { startActivity(startPlaybackScreen) }
+ LabeledButton("Test Transcode") { startActivity(startTranscodeScreen) }
}
}
}
}
}
-
- override fun onPause() {
- super.onPause()
- exoPlayer.pause()
- }
-
- override fun onDestroy() {
- super.onDestroy()
- viewModel.releaseCache()
- exoPlayer.stop()
- exoPlayer.release()
- }
-
- /**
- * This launches the system media picker and stores the resulting URI.
- */
- private val pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
- if (uri != null) {
- Log.d("PhotoPicker", "Selected URI: $uri")
- viewModel.selectedVideo = uri
- viewModel.updateMediaSource(this)
- } else {
- Log.d("PhotoPicker", "No media selected")
- }
- }
-}
-
-@Composable
-fun LabeledButton(buttonLabel: String, modifier: Modifier = Modifier, onClick: () -> Unit) {
- Button(onClick = onClick, modifier = modifier) {
- Text(buttonLabel)
- }
-}
-
-@OptIn(UnstableApi::class)
-@Composable
-fun ExoVideoView(source: MediaSource, exoPlayer: ExoPlayer, modifier: Modifier = Modifier) {
- exoPlayer.playWhenReady = false
- exoPlayer.setMediaSource(source)
- exoPlayer.prepare()
- AndroidView(factory = { context ->
- PlayerView(context).apply {
- player = exoPlayer
- }
- }, modifier = modifier)
-}
-
-@Preview(showBackground = true)
-@Composable
-fun GreetingPreview() {
- SignalTheme {
- LabeledButton("Preview Render") {}
- }
-}
+}
\ No newline at end of file
diff --git a/video/app/src/main/java/org/thoughtcrime/video/app/playback/PlaybackTestActivity.kt b/video/app/src/main/java/org/thoughtcrime/video/app/playback/PlaybackTestActivity.kt
new file mode 100644
index 0000000000..c88b739de3
--- /dev/null
+++ b/video/app/src/main/java/org/thoughtcrime/video/app/playback/PlaybackTestActivity.kt
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2024 Signal Messenger, LLC
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+package org.thoughtcrime.video.app.playback
+
+import android.os.Bundle
+import android.util.Log
+import androidx.activity.compose.setContent
+import androidx.activity.result.PickVisualMediaRequest
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.activity.viewModels
+import androidx.annotation.OptIn
+import androidx.appcompat.app.AppCompatActivity
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Surface
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.viewinterop.AndroidView
+import androidx.media3.common.util.UnstableApi
+import androidx.media3.exoplayer.ExoPlayer
+import androidx.media3.exoplayer.source.MediaSource
+import androidx.media3.ui.PlayerView
+import org.thoughtcrime.video.app.ui.composables.LabeledButton
+import org.thoughtcrime.video.app.ui.theme.SignalTheme
+
+class PlaybackTestActivity : AppCompatActivity() {
+ private val viewModel: PlaybackTestViewModel by viewModels()
+ private lateinit var exoPlayer: ExoPlayer
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ viewModel.initialize(this)
+ exoPlayer = ExoPlayer.Builder(this).build()
+ setContent {
+ SignalTheme {
+ Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
+ Column(
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ val videoUri = viewModel.selectedVideo
+ if (videoUri == null) {
+ LabeledButton("Select Video") { pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.VideoOnly)) }
+ } else {
+ LabeledButton("Play Video") { viewModel.updateMediaSource(this@PlaybackTestActivity) }
+ LabeledButton("Play Video with slow download") { viewModel.updateMediaSourceTrickle(this@PlaybackTestActivity) }
+ ExoVideoView(source = viewModel.mediaSource, exoPlayer = exoPlayer)
+ }
+ }
+ }
+ }
+ }
+ }
+
+ override fun onPause() {
+ super.onPause()
+ exoPlayer.pause()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ viewModel.releaseCache()
+ exoPlayer.stop()
+ exoPlayer.release()
+ }
+
+ /**
+ * This launches the system media picker and stores the resulting URI.
+ */
+ private val pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
+ if (uri != null) {
+ Log.d("PhotoPicker", "Selected URI: $uri")
+ viewModel.selectedVideo = uri
+ viewModel.updateMediaSource(this)
+ } else {
+ Log.d("PhotoPicker", "No media selected")
+ }
+ }
+}
+
+
+@OptIn(UnstableApi::class)
+@Composable
+fun ExoVideoView(source: MediaSource, exoPlayer: ExoPlayer, modifier: Modifier = Modifier) {
+ exoPlayer.playWhenReady = false
+ exoPlayer.setMediaSource(source)
+ exoPlayer.prepare()
+ AndroidView(factory = { context ->
+ PlayerView(context).apply {
+ player = exoPlayer
+ }
+ }, modifier = modifier)
+}
+
+@Preview(showBackground = true)
+@Composable
+fun GreetingPreview() {
+ SignalTheme {
+ LabeledButton("Preview Render") {}
+ }
+}
\ No newline at end of file
diff --git a/video/app/src/main/java/org/thoughtcrime/video/app/MainScreenViewModel.kt b/video/app/src/main/java/org/thoughtcrime/video/app/playback/PlaybackTestViewModel.kt
similarity index 96%
rename from video/app/src/main/java/org/thoughtcrime/video/app/MainScreenViewModel.kt
rename to video/app/src/main/java/org/thoughtcrime/video/app/playback/PlaybackTestViewModel.kt
index a91d6590e3..408ac35df0 100644
--- a/video/app/src/main/java/org/thoughtcrime/video/app/MainScreenViewModel.kt
+++ b/video/app/src/main/java/org/thoughtcrime/video/app/playback/PlaybackTestViewModel.kt
@@ -1,9 +1,9 @@
/*
- * Copyright 2023 Signal Messenger, LLC
+ * Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
-package org.thoughtcrime.video.app
+package org.thoughtcrime.video.app.playback
import android.content.Context
import android.net.Uri
@@ -28,7 +28,7 @@ import java.io.File
* Main screen view model for the video sample app.
*/
@OptIn(UnstableApi::class)
-class MainScreenViewModel : ViewModel() {
+class PlaybackTestViewModel : ViewModel() {
// Initialize an silent media source before the user selects a video. This is the closest I could find to an "empty" media source while still being nullsafe.
private val value by lazy {
val factory = SilenceMediaSource.Factory()
diff --git a/video/app/src/main/java/org/thoughtcrime/video/app/SlowDataSource.kt b/video/app/src/main/java/org/thoughtcrime/video/app/playback/SlowDataSource.kt
similarity index 95%
rename from video/app/src/main/java/org/thoughtcrime/video/app/SlowDataSource.kt
rename to video/app/src/main/java/org/thoughtcrime/video/app/playback/SlowDataSource.kt
index 5406e1e156..887f6f8e4b 100644
--- a/video/app/src/main/java/org/thoughtcrime/video/app/SlowDataSource.kt
+++ b/video/app/src/main/java/org/thoughtcrime/video/app/playback/SlowDataSource.kt
@@ -1,9 +1,9 @@
/*
- * Copyright 2023 Signal Messenger, LLC
+ * Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
-package org.thoughtcrime.video.app
+package org.thoughtcrime.video.app.playback
import android.content.Context
import android.net.Uri
diff --git a/video/app/src/main/java/org/thoughtcrime/video/app/transcode/TranscodeTestActivity.kt b/video/app/src/main/java/org/thoughtcrime/video/app/transcode/TranscodeTestActivity.kt
new file mode 100644
index 0000000000..d4416c562d
--- /dev/null
+++ b/video/app/src/main/java/org/thoughtcrime/video/app/transcode/TranscodeTestActivity.kt
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2024 Signal Messenger, LLC
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+package org.thoughtcrime.video.app.transcode
+
+import androidx.appcompat.app.AppCompatActivity
+
+class TranscodeTestActivity : AppCompatActivity() {
+}
\ No newline at end of file
diff --git a/video/app/src/main/java/org/thoughtcrime/video/app/ui/composables/LabeledButton.kt b/video/app/src/main/java/org/thoughtcrime/video/app/ui/composables/LabeledButton.kt
new file mode 100644
index 0000000000..f03647feef
--- /dev/null
+++ b/video/app/src/main/java/org/thoughtcrime/video/app/ui/composables/LabeledButton.kt
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2024 Signal Messenger, LLC
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+package org.thoughtcrime.video.app.ui.composables
+
+import androidx.compose.material3.Button
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+
+@Composable
+fun LabeledButton(buttonLabel: String, modifier: Modifier = Modifier, onClick: () -> Unit) {
+ Button(onClick = onClick, modifier = modifier) {
+ Text(buttonLabel)
+ }
+}
\ No newline at end of file
diff --git a/video/app/src/main/res/values/strings.xml b/video/app/src/main/res/values/strings.xml
index 06af607989..ffbef093bf 100644
--- a/video/app/src/main/res/values/strings.xml
+++ b/video/app/src/main/res/values/strings.xml
@@ -4,5 +4,5 @@
-->
- Video Player
+ Video Framework Tester
\ No newline at end of file
diff --git a/video/app/src/main/res/values/themes.xml b/video/app/src/main/res/values/themes.xml
index 35ed1d0bff..b51e9d97da 100644
--- a/video/app/src/main/res/values/themes.xml
+++ b/video/app/src/main/res/values/themes.xml
@@ -6,5 +6,5 @@
-
+
\ No newline at end of file