diff --git a/.github/workflows/lastAndroid5.yml b/.github/workflows/lastAndroid5.yml index d955274ff..ce2d25384 100644 --- a/.github/workflows/lastAndroid5.yml +++ b/.github/workflows/lastAndroid5.yml @@ -123,7 +123,14 @@ jobs: app/build/outputs/apk/default/alpha/BV_${{ env.alpha_info_version_code }}_${{ env.alpha_info_version_name }}_default_universal.apk mapping.zip tag_name: ${{ env.tag_name }} +<<<<<<< HEAD + name: ${{ env.alpha_info_version_name }} (Legacy Support For Android 5) + prerelease: true + body: ${{ env.changelog }} + target_commitish: ${{ github.sha }} +======= name: ${{ env.alpha_info_version_name }} prerelease: true body: ${{ env.changelog }} - target_commitish: ${{ github.sha }} \ No newline at end of file + target_commitish: ${{ github.sha }} +>>>>>>> develop diff --git a/README.md b/README.md index 29ffaabdd..e0edcff6c 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,11 @@ [![Android Sdk Require](https://img.shields.io/badge/Android-6.0%2B-informational?logo=android)](https://developer.android.com/jetpack/androidx/versions#version-table) [![GitHub](https://img.shields.io/github/license/Colorful-glassblock/bvcn)](https://github.com/Colorful-glassblock/bvcn) +<<<<<<< HEAD +**BV ~~无法~~可以在中国大陆地区内的智能电视上使用,如有相关使用需求请使用 [云视听小电视](https://app.bilibili.com)** + +**~~禁止~~允许在中国境内传播、宣传、分发 BV** +======= **BVCN ~~无法~~可以在中国大陆地区内的智能电视上使用,如有相关使用需求请使用 [云视听小电视(不是哥们你真用啊)](https://app.bilibili.com)** **~~禁止~~允许在中国境内传播、宣传、分发 BVCN** @@ -21,6 +26,7 @@ **由于fucking又stupid的bilibili官方对BAC大打出手 本项目以后可能不再可用 目前评论区功能已经不正常** **R.I.P. Bilibili-API-collect 感谢此项目对bilibili接口的收集 否则非官方bilibili client开发将十分艰难** **愿bilibili不会变质 可惜已经变了** +>>>>>>> develop diff --git a/app/mobile/src/main/kotlin/dev/aaa1115910/bv/mobile/screen/RegionBlockScreen.kt b/app/mobile/src/main/kotlin/dev/aaa1115910/bv/mobile/screen/RegionBlockScreen.kt deleted file mode 100644 index b07499abf..000000000 --- a/app/mobile/src/main/kotlin/dev/aaa1115910/bv/mobile/screen/RegionBlockScreen.kt +++ /dev/null @@ -1,107 +0,0 @@ -package dev.aaa1115910.bv.mobile.screen - -import android.app.Activity -import android.content.res.Configuration -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.widthIn -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.WarningAmber -import androidx.compose.material3.FilledTonalButton -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import dev.aaa1115910.bv.R -import dev.aaa1115910.bv.mobile.theme.BVMobileTheme -import kotlin.system.exitProcess - -@Composable -fun RegionBlockScreen(modifier: Modifier = Modifier) { - val context = LocalContext.current - - val exitApp: () -> Unit = { - (context as Activity).finish() - exitProcess(0) - } - - RegionBlockContent( - modifier = modifier, - onExit = exitApp - ) -} - -@Composable -private fun RegionBlockContent( - modifier: Modifier = Modifier, - onExit: () -> Unit -) { - Scaffold( - modifier = modifier - ) { innerPadding -> - Box( - modifier = Modifier - .padding(innerPadding) - .fillMaxSize() - ) { - Column( - modifier = Modifier - .padding(horizontal = 24.dp) - .align(Alignment.Center), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(24.dp) - ) { - Icon( - modifier = Modifier.size(32.dp), - imageVector = Icons.Default.WarningAmber, - contentDescription = null, - tint = MaterialTheme.colorScheme.error - ) - Text( - text = stringResource(R.string.region_block_title), - style = MaterialTheme.typography.titleLarge, - textAlign = TextAlign.Center - ) - Text( - text = stringResource(R.string.region_block_subtitle_mobile), - style = MaterialTheme.typography.bodySmall, - textAlign = TextAlign.Center - ) - } - FilledTonalButton( - modifier = Modifier - .align(Alignment.BottomCenter) - .padding(horizontal = 24.dp, vertical = 12.dp) - .widthIn(max = 320.dp) - .fillMaxWidth(), - onClick = onExit - ) { - Text(text = stringResource(R.string.region_block_exit_button)) - } - } - } -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun RegionBlockScreenPreview() { - BVMobileTheme { - RegionBlockContent( - onExit = {} - ) - } -} \ No newline at end of file diff --git a/app/mobile/src/main/kotlin/dev/aaa1115910/bv/mobile/screen/settings/details/PlayContent.kt b/app/mobile/src/main/kotlin/dev/aaa1115910/bv/mobile/screen/settings/details/PlayContent.kt index 9abf13f4b..bf6444c12 100644 --- a/app/mobile/src/main/kotlin/dev/aaa1115910/bv/mobile/screen/settings/details/PlayContent.kt +++ b/app/mobile/src/main/kotlin/dev/aaa1115910/bv/mobile/screen/settings/details/PlayContent.kt @@ -9,12 +9,20 @@ import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +<<<<<<< HEAD +import de.schnettler.datastore.manager.DataStoreManager +import dev.aaa1115910.bv.dataStore +import dev.aaa1115910.bv.mobile.component.preferences.RadioPreferenceItem +import dev.aaa1115910.bv.mobile.component.preferences.SwitchPreferenceItem +import dev.aaa1115910.bv.mobile.component.preferences.getOrDefault +======= import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import dev.aaa1115910.bv.mobile.component.preferences.items.radioPreference import dev.aaa1115910.bv.mobile.component.preferences.items.switchPreference import dev.aaa1115910.bv.mobile.component.preferences.preferenceGroups import dev.aaa1115910.bv.mobile.theme.BVMobileTheme +>>>>>>> develop import dev.aaa1115910.bv.player.entity.Audio import dev.aaa1115910.bv.player.entity.Resolution import dev.aaa1115910.bv.player.entity.VideoCodec @@ -62,6 +70,11 @@ fun PlayContent( ) } ) + SwitchPreferenceItem( + title = "启用视频软解", + summary = "使用软件解码器播放视频,可能解决硬解兼容性问题", + prefReq = PrefKeys.prefEnableSoftwareVideoRendererRequest + ) } } diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index a42b6bc27..7724b839b 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -90,6 +90,8 @@ # ktor 混淆后,请求参数会莫名其妙消失 -keep class io.ktor.** +-keep class dev.aaa1115910.biliapi.http.plugins.** { *; } +-keep class dev.aaa1115910.biliapi.http.util.** { *; } # 这部分是加上不混淆 ktor 后冒出来的 missing rules -dontwarn java.lang.management.ManagementFactory -dontwarn java.lang.management.RuntimeMXBean diff --git a/app/shared/src/main/kotlin/dev/aaa1115910/bv/network/GithubApi.kt b/app/shared/src/main/kotlin/dev/aaa1115910/bv/network/GithubApi.kt index 278be1dec..958adb020 100644 --- a/app/shared/src/main/kotlin/dev/aaa1115910/bv/network/GithubApi.kt +++ b/app/shared/src/main/kotlin/dev/aaa1115910/bv/network/GithubApi.kt @@ -29,8 +29,20 @@ import java.io.File object GithubApi { private var endPoint = "api.github.com" - private const val OWNER = "aaa1115910" - private const val REPO = "bv" + private const val OWNER = "Colorful-glassblock" + private const val REPO = "bvcn" + // 当前分支名称,用于过滤对应分支的 release + private const val CURRENT_BRANCH = "lastAndroid5" + // 电视端特殊处理:如果在 TV 上运行,允许获取所有 release(因为 TV 可能需要更多版本) + private val isTvDevice: Boolean + get() { + return try { + val uiModeManager = LocalContext.current.getSystemService(Context.UI_MODE_SERVICE) as UiModeManager + uiModeManager.currentModeType == Configuration.UI_MODE_TYPE_TELEVISION + } catch (e: Exception) { + false + } + private lateinit var client: HttpClient private val json = Json { coerceInputValues = true @@ -74,16 +86,26 @@ object GithubApi { parameter("page", page) }.bodyAsText() checkErrorMessage(response) - return json.decodeFromString>(response) + val allReleases = json.decodeFromString>(response) +<<<<<<< HEAD + // 电视端特殊处理:如果在 TV 上运行,允许获取所有 release + if (isTvDevice) { + return allReleases + } + // 其他设备:过滤只匹配当前分支的 release +======= + // 过滤只匹配当前分支的 release +>>>>>>> develop + return allReleases.filter { it.targetCommitish == CURRENT_BRANCH } } private suspend fun getLatestRelease( owner: String = OWNER, repo: String = REPO ): Release { - val response = client.get("repos/$owner/$repo/releases/latest").bodyAsText() - checkErrorMessage(response) - return json.decodeFromString(response) + val releases = getReleases(owner = owner, repo = repo, pageSize = 1) + return releases.firstOrNull { !it.isPreRelease } + ?: throw IllegalStateException("No release found for branch $CURRENT_BRANCH") } suspend fun getLatestPreReleaseBuild(): Release { @@ -95,7 +117,7 @@ object GithubApi { release = releases.firstOrNull { it.isPreRelease } page++ } - return release ?: throw IllegalStateException("No pre-release found") + return release ?: throw IllegalStateException("No pre-release found for branch $CURRENT_BRANCH") } suspend fun getLatestReleaseBuild(): Release = getLatestRelease() diff --git a/app/shared/src/main/kotlin/dev/aaa1115910/bv/viewmodel/VideoPlayerV3ViewModel.kt b/app/shared/src/main/kotlin/dev/aaa1115910/bv/viewmodel/VideoPlayerV3ViewModel.kt index a52f684d1..19e4d6d53 100644 --- a/app/shared/src/main/kotlin/dev/aaa1115910/bv/viewmodel/VideoPlayerV3ViewModel.kt +++ b/app/shared/src/main/kotlin/dev/aaa1115910/bv/viewmodel/VideoPlayerV3ViewModel.kt @@ -403,7 +403,11 @@ class VideoPlayerV3ViewModel( currentVideoWidth = videoItem?.width ?: 0 logger.info { "Video url: $videoUrl" } logger.info { "Audio url: $audioUrl" } +<<<<<<< HEAD + // 将 playUrl 移到 IO 线程,避免主线程卡顿 +======= // 将 playUrl 移到 IO 线程,避免主线程阻塞 +>>>>>>> develop withContext(Dispatchers.IO) { videoPlayer!!.playUrl(videoUrl, audioUrl) } diff --git a/app/tv/src/main/kotlin/dev/aaa1115910/bv/tv/screens/VideoPlayerV3Screen.kt b/app/tv/src/main/kotlin/dev/aaa1115910/bv/tv/screens/VideoPlayerV3Screen.kt index 82227b64c..8d6bb099d 100644 --- a/app/tv/src/main/kotlin/dev/aaa1115910/bv/tv/screens/VideoPlayerV3Screen.kt +++ b/app/tv/src/main/kotlin/dev/aaa1115910/bv/tv/screens/VideoPlayerV3Screen.kt @@ -191,10 +191,13 @@ fun VideoPlayerV3Screen( Prefs.defaultSubtitleBottomPadding = padding playerViewModel.currentSubtitleBottomPadding = padding }, +<<<<<<< HEAD +======= onPlayModeChange = { playMode -> Prefs.defaultPlayMode = playMode playerViewModel.currentPlayMode = playMode }, +>>>>>>> develop onUpdateDanmakuForPosition = playerViewModel::updateDanmakuForPosition ) } diff --git a/player/tv/src/main/kotlin/dev/aaa1115910/bv/player/tv/BvPlayer.kt b/player/tv/src/main/kotlin/dev/aaa1115910/bv/player/tv/BvPlayer.kt index afa39fc17..8ace6dc51 100644 --- a/player/tv/src/main/kotlin/dev/aaa1115910/bv/player/tv/BvPlayer.kt +++ b/player/tv/src/main/kotlin/dev/aaa1115910/bv/player/tv/BvPlayer.kt @@ -100,7 +100,10 @@ fun BvPlayer( onSubtitleSizeChange: (TextUnit) -> Unit, onSubtitleBackgroundOpacityChange: (Float) -> Unit, onSubtitleBottomPadding: (Dp) -> Unit, +<<<<<<< HEAD +======= onPlayModeChange: (PlayMode) -> Unit, +>>>>>>> develop onUpdateDanmakuForPosition: (suspend (Long) -> Unit)? = null ) { val scope = rememberCoroutineScope()