This commit is contained in:
1
2026-04-27 15:31:36 +08:00
parent ca9d68ace4
commit f63c4150b4
8 changed files with 62 additions and 25 deletions

View File

@@ -17,8 +17,8 @@ android {
applicationId = "com.donut.mixfile"
minSdk = 26
targetSdk = 36
versionCode = 155
versionName = "2.0.9"
versionCode = 157
versionName = "2.0.9.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
@@ -69,6 +69,8 @@ android {
dependencies {
// 引用 libs 目录下的所有 aar
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.aar"))))
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0")
implementation("com.github.InvertGeek:mixfile-core:2.0.8")
implementation("androidx.compose.material:material-icons-extended:1.7.8")

Binary file not shown.

View File

@@ -17,6 +17,7 @@
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:extractNativeLibs="true"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_config"
android:roundIcon="@mipmap/ic_launcher"

View File

@@ -169,7 +169,7 @@ fun BottomControl(
onClick = {
MixDialogBuilder(
"选集",
scheme = playerColorScheme
colorScheme = playerColorScheme
).apply {
val indexMap =
videos.mapIndexed { index, uri -> index to uri }
@@ -206,7 +206,7 @@ fun BottomControl(
onClick = {
MixDialogBuilder(
"播放速度",
scheme = playerColorScheme
colorScheme = playerColorScheme
).apply {
setContent {
SingleSelectItemList(

View File

@@ -3,6 +3,7 @@ package com.donut.mixfile.activity.video.player
import android.net.Uri
import android.widget.Toast
import androidx.annotation.OptIn
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
@@ -26,13 +27,21 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.media3.common.MediaItem
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.common.Player.REPEAT_MODE_ALL
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.DefaultRenderersFactory
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
import androidx.media3.extractor.DefaultExtractorsFactory
import androidx.media3.extractor.ts.DefaultTsPayloadReaderFactory
import androidx.media3.ui.PlayerView
import com.donut.mixfile.activity.video.VideoHistory
import com.donut.mixfile.activity.video.playHistory
import com.donut.mixfile.ui.theme.mainColorScheme
import com.donut.mixfile.util.ForceUpdateMutable
import com.donut.mixfile.util.showErrorDialog
import com.donut.mixfile.util.showToast
import kotlinx.coroutines.delay
import java.util.Locale
@@ -56,6 +65,7 @@ val playerColorScheme
onSecondaryContainer = mainColorScheme.primary.copy(0.8f)
)
@OptIn(UnstableApi::class)
@Composable
fun VideoPlayerScreen(
videoUris: List<Uri>,
@@ -64,21 +74,42 @@ fun VideoPlayerScreen(
) {
val context = LocalContext.current
val player = remember {
ExoPlayer.Builder(context).build().apply {
setMediaItems(videoUris.map { MediaItem.fromUri(it) })
repeatMode = REPEAT_MODE_ALL
val cached = playHistory.firstOrNull { it.hash.contentEquals(hash) }
if (cached != null) {
setMediaItems(
videoUris.map { MediaItem.fromUri(it) },
cached.episode,
(cached.time - 2000L).coerceAtLeast(0)
)
showToast("已跳转到上次播放位置", length = Toast.LENGTH_SHORT)
}
prepare()
playWhenReady = true
// 1. 创建渲染器工厂
val renderersFactory = DefaultRenderersFactory(context).apply {
setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER)
}
val extractorsFactory = DefaultExtractorsFactory().apply {
// 开启对所有可能的容器支持
setConstantBitrateSeekingEnabled(true) // 允许对没有索引的流进行粗略进度拖动
setTsExtractorFlags(DefaultTsPayloadReaderFactory.FLAG_ENABLE_HDMV_DTS_AUDIO_STREAMS)
}
ExoPlayer.Builder(context, renderersFactory)
.setMediaSourceFactory(DefaultMediaSourceFactory(context, extractorsFactory))
.build()
.apply {
addListener(object : Player.Listener {
override fun onPlayerError(error: PlaybackException) {
showErrorDialog(error, "播放出错", playerColorScheme)
}
})
setMediaItems(videoUris.map { MediaItem.fromUri(it) })
repeatMode = REPEAT_MODE_ALL
val cached = playHistory.firstOrNull { it.hash.contentEquals(hash) }
if (cached != null) {
setMediaItems(
videoUris.map { MediaItem.fromUri(it) },
cached.episode,
(cached.time - 2000L).coerceAtLeast(0)
)
showToast("已跳转到上次播放位置", length = Toast.LENGTH_SHORT)
}
prepare()
playWhenReady = true
}
}
var currentMediaItem by remember { mutableIntStateOf(player.currentMediaItemIndex) }

View File

@@ -20,9 +20,9 @@ var CUSTOM_UPLOAD_URL by cachedMutableOf("", "CUSTOM_UPLOAD_URL")
var CUSTOM_REFERER by cachedMutableOf("", "CUSTOM_REFERER")
val UPLOADERS = listOf(A1Uploader, A2Uploader, A3Uploader, CustomUploader, JavaScriptUploader)
val UPLOADERS = listOf(CustomUploader, JavaScriptUploader)
val DEFAULT_UPLOADER = A2Uploader
val DEFAULT_UPLOADER = JavaScriptUploader
var currentUploader by cachedMutableOf(DEFAULT_UPLOADER.name, "current_uploader")

View File

@@ -34,7 +34,7 @@ class MixDialogBuilder(
private val iconContentColor: Color? = null,
private val titleContentColor: Color? = null,
private val textContentColor: Color? = null,
private val scheme: ColorScheme? = null,
private val colorScheme: ColorScheme? = null,
) {
private var content = @Composable {}
private var positiveButton = @Composable {}
@@ -114,7 +114,7 @@ class MixDialogBuilder(
iconContentColor,
titleContentColor,
textContentColor,
scheme
colorScheme
)
dialogCache[tag]?.invoke()
dialogCache[tag] = close

View File

@@ -224,8 +224,12 @@ fun showConfirmDialog(title: String, subtitle: String = "", onConfirm: () -> Uni
}
fun showErrorDialog(e: Throwable, title: String = "发生错误") {
MixDialogBuilder(title).apply {
fun showErrorDialog(
e: Throwable,
title: String = "发生错误",
colorScheme: ColorScheme = mainColorScheme
) {
MixDialogBuilder(title, colorScheme = colorScheme).apply {
setContent {
Column(
modifier = Modifier
@@ -249,4 +253,3 @@ fun showErrorDialog(e: Throwable, title: String = "发生错误") {
show()
}
}