Skip to content

Commit ff80ef8

Browse files
authored
Add video playback with exoplayer (#5)
* Media3 and Exoplayer setup * Add video for exoplayer, make exoplayer fullscreen, change some visual details * Moved exoplayer to ViewModel fixing playback restart on configuration change * Added custom overlay for video * Resize overlay to the same size as video * Added slider for showing progress * Added seeking and time * Readme update * Code reformatting
1 parent 0782d23 commit ff80ef8

File tree

22 files changed

+545
-5
lines changed

22 files changed

+545
-5
lines changed

.editorconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ ij_kotlin_extends_list_wrap = normal
6060
ij_kotlin_field_annotation_wrap = split_into_lines
6161
ij_kotlin_finally_on_new_line = false
6262
ij_kotlin_if_rparen_on_new_line = true
63-
ij_kotlin_import_nested_classes = true
6463
ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^
6564
ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
6665
ij_kotlin_keep_blank_lines_before_right_brace = 0

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ Splash screen
1010

1111
<img src="readme_res/splash_screen_20240703.gif" width="480"/>
1212

13+
Exoplayer video playback
14+
15+
![exoplayer](readme_res/exoplayer_20241115.gif)
16+
1317
### Quick overview
1418

1519
| Feature | Short description |

app/src/main/java/com/featuremodule/template/ui/AppNavBar.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import androidx.compose.runtime.Composable
77
import androidx.compose.ui.res.stringResource
88
import androidx.navigation.NavDestination
99
import androidx.navigation.NavDestination.Companion.hierarchy
10+
import com.featuremodule.core.navigation.HIDE_NAV_BAR
1011
import com.featuremodule.core.navigation.NavBarItems
1112

1213
/**
@@ -24,6 +25,8 @@ internal fun AppNavBar(
2425
openNavBarRoute: (route: String, isSelected: Boolean) -> Unit,
2526
currentDestination: NavDestination?,
2627
) {
28+
if (currentDestination?.route.orEmpty().contains(HIDE_NAV_BAR)) return
29+
2730
NavigationBar {
2831
NavBarItems.entries.forEach { item ->
2932
val isSelected = currentDestination?.hierarchy
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.featuremodule.core.navigation
2+
3+
/** Appended to the start of a route to sign that NavigationBar should be hidden */
4+
const val HIDE_NAV_BAR = "hide_nav_bar/"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.featuremodule.core.util
2+
3+
import android.app.Activity
4+
import android.content.Context
5+
import android.content.ContextWrapper
6+
7+
tailrec fun Context.getActivity(): Activity? = when (this) {
8+
is Activity -> this
9+
is ContextWrapper -> baseContext.getActivity()
10+
else -> null
11+
}

core/src/main/java/com/featuremodule/core/util/Utils.kt renamed to core/src/main/java/com/featuremodule/core/util/FlowUtils.kt

File renamed without changes.

detekt-config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ naming:
366366
packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*'
367367
TopLevelPropertyNaming:
368368
active: true
369-
constantPattern: '[A-Z][A-Za-z0-9]*'
369+
constantPattern: '[A-Za-z][_A-Za-z0-9]*'
370370
propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
371371
privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*'
372372
VariableMaxLength:

feature/homeImpl/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@ android {
99
dependencies {
1010
implementation(projects.feature.homeApi)
1111
implementation(projects.feature.featureAApi)
12+
13+
implementation(libs.bundles.exoplayer)
1214
}

feature/homeImpl/src/main/java/com/featuremodule/homeImpl/HomeGraphEntry.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,25 @@ package com.featuremodule.homeImpl
22

33
import androidx.navigation.NavGraphBuilder
44
import androidx.navigation.compose.composable
5+
import com.featuremodule.core.navigation.HIDE_NAV_BAR
56
import com.featuremodule.homeApi.HomeDestination
7+
import com.featuremodule.homeImpl.exoplayer.ExoplayerScreen
68
import com.featuremodule.homeImpl.ui.HomeScreen
79

810
fun NavGraphBuilder.registerHome() {
911
composable(HomeDestination.ROUTE) { backStackEntry ->
1012
HomeScreen(route = backStackEntry.destination.route)
1113
}
14+
15+
composable(InternalRoutes.ExoplayerDestination.ROUTE) {
16+
ExoplayerScreen()
17+
}
18+
}
19+
20+
internal sealed class InternalRoutes {
21+
object ExoplayerDestination {
22+
const val ROUTE = HIDE_NAV_BAR + "exoplayer"
23+
24+
fun constructRoute() = ROUTE
25+
}
1226
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.featuremodule.homeImpl.exoplayer
2+
3+
import androidx.media3.exoplayer.ExoPlayer
4+
import com.featuremodule.core.ui.UiEvent
5+
import com.featuremodule.core.ui.UiState
6+
7+
internal data class State(
8+
val exoplayer: ExoPlayer,
9+
val overlayState: OverlayState = OverlayState(),
10+
) : UiState
11+
12+
internal data class OverlayState(
13+
val showPlayButton: Boolean = false,
14+
val title: String = "",
15+
val contentPosition: Long = 0,
16+
val contentDuration: Long = 0,
17+
)
18+
19+
internal sealed interface Event : UiEvent {
20+
data object OnPlayPauseClick : Event
21+
data class OnSeekFinished(val position: Long) : Event
22+
}

0 commit comments

Comments
 (0)