Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,11 @@ dependencies {
implementation(libs.androidx.compose.animation.graphics)
implementation(libs.mediasession)
implementation(libs.androidx.documentfile)
implementation(libs.androidx.datastore.core)
implementation(libs.androidx.datastore.preferences)
implementation(libs.bundles.coil)


implementation(platform(libs.koin.bom))
implementation(libs.bundles.koin)

Expand All @@ -212,11 +215,21 @@ dependencies {
implementation(libs.room.ktx)

implementation(libs.kotlinx.immutable.collections)
implementation(libs.kotlinx.coroutines.guava)
implementation(libs.kotlinx.serialization.json)

implementation(libs.okhttp)
implementation(libs.jsoup)
implementation(libs.androidx.media3.common)
implementation(libs.androidx.media3.datasource.okhttp)
implementation(libs.androidx.media3.effect)
implementation(libs.androidx.media3.exoplayer)
implementation(libs.androidx.media3.exoplayer.dash)
implementation(libs.androidx.media3.exoplayer.hls)
implementation(libs.androidx.media3.exoplayer.rtsp)
implementation(libs.androidx.media3.session)
implementation(libs.androidx.media3.ui)
implementation(libs.androidx.media3.ui.compose)
implementation(libs.androidx.media3.transformer)
implementation(platform(libs.sora.editor.bom))
implementation(libs.sora.editor)
Expand All @@ -226,11 +239,17 @@ dependencies {
coreLibraryDesugaring(libs.desugar.jdk.libs)

implementation(libs.truetype.parser)
implementation(libs.juniversalchardet)
implementation(libs.ass.media)
implementation(libs.fsaf)


implementation(libs.mediainfo.lib)
implementation("com.llamatik:library:1.4.0")

implementation(files("libs/mpvlib.aar"))
implementation(files("libs/media3ext-release.aar"))


// Network protocol libraries
implementation(libs.smbj)
Expand Down
Binary file added app/libs/media3ext-release.aar
Binary file not shown.
18 changes: 18 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,24 @@
<data android:pathPattern=".*" />
</intent-filter>
</activity>
<activity
android:name=".exoplayer.ExoPlayerActivity"
android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:exported="false"
android:launchMode="singleTask"
android:resizeableActivity="true"
android:supportsPictureInPicture="true"
android:theme="@style/Theme.mpvrx.Player" />

<service
android:name=".exoplayer.ExoPlayerService"
android:exported="true"
android:foregroundServiceType="mediaPlayback">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>

<activity android:name=".presentation.crash.CrashActivity" />

<activity
Expand Down
24 changes: 15 additions & 9 deletions app/src/main/java/app/gyrolet/mpvrx/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,21 @@ class App : Application() {
override fun onCreate() {
super.onCreate()

// Initialize Koin
startKoin {
androidContext(this@App)
modules(
PreferencesModule,
DatabaseModule,
FileManagerModule,
app.gyrolet.mpvrx.di.domainModule,
)
try {
android.util.Log.d("App", "Starting Koin...")
startKoin {
androidContext(this@App)
modules(
PreferencesModule,
DatabaseModule,
FileManagerModule,
app.gyrolet.mpvrx.di.domainModule,
app.gyrolet.mpvrx.exoplayer.di.exoPlayerModule,
)
}
android.util.Log.d("App", "Koin initialized successfully")
} catch (e: Exception) {
android.util.Log.e("App", "Koin initialization failed!", e)
}

Thread.setDefaultUncaughtExceptionHandler(GlobalExceptionHandler(applicationContext, CrashActivity::class.java))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ class AppearancePreferences(
val topRightControls =
preferenceStore.getString(
"top_right_controls",
"CURRENT_CHAPTER,DECODER,AUDIO_TRACK,SUBTITLES,MORE_OPTIONS",
"CURRENT_CHAPTER,DECODER,AUDIO_TRACK,SUBTITLES,TIME_NETWORK,VIDEO_FILTERS,MORE_OPTIONS",
)

val bottomRightControls =
preferenceStore.getString(
"bottom_right_controls",
"FRAME_NAVIGATION,VIDEO_ZOOM,PICTURE_IN_PICTURE,ASPECT_RATIO",
"FRAME_NAVIGATION,VIDEO_ZOOM,PICTURE_IN_PICTURE,ASPECT_RATIO,AMBIENT_MODE",
)

val bottomLeftControls =
Expand All @@ -62,7 +62,7 @@ class AppearancePreferences(
val portraitBottomControls =
preferenceStore.getString(
"portrait_bottom_controls",
"SCREEN_ROTATION,DECODER,AUDIO_TRACK,SUBTITLES,BOOKMARKS_CHAPTERS,PLAYBACK_SPEED,BACKGROUND_PLAYBACK,REPEAT_MODE,SHUFFLE,VIDEO_ZOOM,FRAME_NAVIGATION,ASPECT_RATIO,PICTURE_IN_PICTURE,LOCK_CONTROLS,MORE_OPTIONS",
"SCREEN_ROTATION,DECODER,AUDIO_TRACK,SUBTITLES,BOOKMARKS_CHAPTERS,PLAYBACK_SPEED,BACKGROUND_PLAYBACK,REPEAT_MODE,SHUFFLE,VIDEO_ZOOM,FRAME_NAVIGATION,ASPECT_RATIO,PICTURE_IN_PICTURE,LOCK_CONTROLS,TIME_NETWORK,AMBIENT_MODE,VIDEO_FILTERS,MORE_OPTIONS",
)

fun parseButtons(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ enum class PlayerButton(
BACKGROUND_PLAYBACK(Icons.Outlined.Headset),
AMBIENT_MODE(Icons.Outlined.BlurOff),
TIME_NETWORK(Icons.Default.AccessTime),
VIDEO_FILTERS(Icons.Default.Tune),
NONE(Icons.Outlined.Bookmarks),
}

Expand Down Expand Up @@ -82,5 +83,6 @@ fun getPlayerButtonLabel(button: PlayerButton): String =
PlayerButton.BACKGROUND_PLAYBACK -> "Background Playback"
PlayerButton.AMBIENT_MODE -> "Ambience Mode"
PlayerButton.TIME_NETWORK -> "Time + Network"
PlayerButton.VIDEO_FILTERS -> "Video Filters"
PlayerButton.NONE -> "None"
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ class PlayerPreferences(
val keepScreenOnWhenPaused = preferenceStore.getBoolean("keep_screen_on_when_paused", false)
val autoplayAfterScreenUnlock = preferenceStore.getBoolean("autoplay_after_screen_unlock", false)

val enableExoPlayer = preferenceStore.getBoolean("enable_exoplayer", false)

// Custom Buttons - JSON List
val customButtons = preferenceStore.getString("custom_buttons_json", "[]")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.FilledIconButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBarDefaults
import androidx.compose.material3.OutlinedButton
Expand Down Expand Up @@ -70,6 +69,7 @@ import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.inject
import org.koin.core.context.GlobalContext
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
Expand All @@ -81,21 +81,36 @@ class CrashActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val exception = intent.getStringExtra("exception") ?: "No exception provided"
android.util.Log.e("CrashActivity", "CRASH DETECTED: $exception")
lifecycle.coroutineScope.launch {
logcat = collectLogcat()
}
setContent {
val dark by appearancePreferences.darkMode.collectAsState()
val isSystemInDarkTheme = isSystemInDarkTheme()
val isDarkMode = dark == DarkMode.Dark || (dark == DarkMode.System && isSystemInDarkTheme)
enableEdgeToEdge(
SystemBarStyle.auto(
lightScrim = Color.White.toArgb(),
darkScrim = Color.Transparent.toArgb(),
) { isDarkMode },
)
MpvrxTheme {
CrashScreen(intent.getStringExtra("exception") ?: "")
if (GlobalContext.getOrNull() != null) {
val dark by appearancePreferences.darkMode.collectAsState()
val isSystemInDarkTheme = isSystemInDarkTheme()
val isDarkMode = dark == DarkMode.Dark || (dark == DarkMode.System && isSystemInDarkTheme)
enableEdgeToEdge(
SystemBarStyle.auto(
lightScrim = Color.White.toArgb(),
darkScrim = Color.Transparent.toArgb(),
) { isDarkMode },
)
MpvrxTheme {
CrashScreen(intent.getStringExtra("exception") ?: "")
}
} else {
val isDarkMode = isSystemInDarkTheme()
enableEdgeToEdge(
SystemBarStyle.auto(
lightScrim = Color.White.toArgb(),
darkScrim = Color.Transparent.toArgb(),
) { isDarkMode },
)
MaterialTheme {
CrashScreen(intent.getStringExtra("exception") ?: "")
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ class GlobalExceptionHandler(
val intent = Intent(context, activity)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
intent.putExtra("exception", e.stackTraceToString())
val stackTrace = e.stackTraceToString()
android.util.Log.e("GlobalExceptionHandler", "CRASH DETECTED: $stackTrace")
intent.putExtra("exception", stackTrace)
context.startActivity(intent)
exitProcess(0)
}
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/app/gyrolet/mpvrx/ui/icons/Icons.kt
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ object Icons {
val Refresh = Shared.Refresh
val Remove = Shared.Remove
val RemoveCircle = Shared.RemoveCircle
val Repeat = Shared.Repeat
val RepeatOn = Shared.RepeatOn
val RepeatOne = Shared.RepeatOne
val ResetIso = Shared.ResetIso
val RoundedCorner = Shared.RoundedCorner
val ScreenRotation = Shared.ScreenRotation
Expand Down Expand Up @@ -422,6 +425,8 @@ object Icons {
val PictureInPictureAlt = Shared.PictureInPictureAlt
val PlaylistAdd = Shared.PlaylistAdd
val Repeat = Shared.Repeat
val RepeatOn = Shared.RepeatOn
val RepeatOne = Shared.RepeatOne
val ScreenRotation = Shared.ScreenRotation
val Search = Shared.Search
val Settings = Shared.Settings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,15 @@ fun RenderPlayerButton(
}
}

PlayerButton.VIDEO_FILTERS -> {
ControlsButton(
icon = Icons.Default.Tune,
onClick = { onOpenPanel(Panels.VideoFilters) },
color = if (hideBackground) controlColor else MaterialTheme.colorScheme.onSurface,
modifier = Modifier.size(buttonSize),
)
}

PlayerButton.NONE -> { /* Do nothing */
}
}
Expand Down
Loading
Loading