From 10f7c68a45666d09c7b5e17f5bce31844dcdafda Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Tue, 12 Mar 2024 23:14:05 +0800 Subject: [PATCH 01/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- buildSrc/src/main/kotlin/AppConfiguration.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/AppConfiguration.kt b/buildSrc/src/main/kotlin/AppConfiguration.kt index 96420d40..657dfaa9 100644 --- a/buildSrc/src/main/kotlin/AppConfiguration.kt +++ b/buildSrc/src/main/kotlin/AppConfiguration.kt @@ -5,7 +5,7 @@ object AppConfiguration { const val targetSdk = 34 private const val major = 0 private const val minor = 2 - private const val patch = 6 + private const val patch = 7 private const val bugFix = 0 @Suppress("KotlinConstantConditions") From e1a72b2fae0a2507e37fdf3631ff1d8d3bdc5c55 Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Tue, 12 Mar 2024 23:15:48 +0800 Subject: [PATCH 02/19] =?UTF-8?q?=E8=A7=86=E9=A2=91=E8=AF=A6=E7=BB=86?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=20TAG=20=E5=AD=97=E6=AE=B5=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=EF=BC=88Web=E6=8E=A5=E5=8F=A3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixed #127 --- .../aaa1115910/biliapi/entity/video/Tag.kt | 5 ++++ .../biliapi/http/entity/video/VideoDetail.kt | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/Tag.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/Tag.kt index 69a96ee4..2d43129b 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/Tag.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/Tag.kt @@ -14,5 +14,10 @@ data class Tag( id = tag.id.toInt(), name = tag.name ) + + fun fromTag(tag: dev.aaa1115910.biliapi.http.entity.video.VideoDetail.Tag) = Tag( + id = tag.tagId, + name = tag.tagName + ) } } diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/VideoDetail.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/VideoDetail.kt index cc804ad1..515f3049 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/VideoDetail.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/VideoDetail.kt @@ -38,4 +38,27 @@ data class VideoDetail( val show: Boolean, val list: JsonArray ) + + /** + * 视频 TAG + * + * @param tagId TAG ID 当存在[musicId]时可能为 0 + * @param tagName TAG名称 + * @param musicId 音乐ID + * @param tagType TAG类型 bgm old_channel topic + * @param jumpUrl 跳转链接 + */ + @Serializable + data class Tag( + @SerialName("tag_id") + val tagId: Int, + @SerialName("tag_name") + val tagName: String, + @SerialName("music_id") + val musicId: String, + @SerialName("tag_type") + val tagType: String, + @SerialName("jump_url") + val jumpUrl: String + ) } From daba19bc848e96d20bd4e96925ebd572ad12e29b Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Wed, 13 Mar 2024 00:54:57 +0800 Subject: [PATCH 03/19] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20issue=20=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E4=BC=9A=E6=B7=BB=E5=8A=A0=20task=20list=20=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE/bug_report.yml | 9 +++++---- .github/workflows/auto_close_issues.yml | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/auto_close_issues.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index e454c468..2b7373c3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -45,18 +45,19 @@ body: attributes: label: 截图 description: 如果可以,提交截图更有助于我们分析问题 - - type: checkboxes + - type: dropdown id: app-version-confirm-use-latest validations: required: true attributes: - label: 该项目不确认已更新到以下所示的最新版本 + label: 请确认已更新到以下所示的最新版本 description: | ![App Center Release](https://img.shields.io/endpoint?url=https%3A%2F%2Fbadge.versions.bv.aaa1115910.dev%2F%3Ftype%3Drelease) ![App Center Alpha](https://img.shields.io/endpoint?url=https%3A%2F%2Fbadge.versions.bv.aaa1115910.dev%2F%3Ftype%3Dalpha) options: - - label: 我已更新到最新版本 - required: true + - '我正在使用旧版本' + - '已更新到最新 Release 版' + - '已更新到最新 Alpha 版' - type: input id: app-version validations: diff --git a/.github/workflows/auto_close_issues.yml b/.github/workflows/auto_close_issues.yml new file mode 100644 index 00000000..87b029c8 --- /dev/null +++ b/.github/workflows/auto_close_issues.yml @@ -0,0 +1,15 @@ +name: Check Issues + +on: + issues: + types: [opened] +jobs: + check: + runs-on: ubuntu-latest + steps: + - if: contains(github.event.issue.body, '我正在使用旧版本' ) + id: close-old-version + name: Close Issue(template) + uses: peter-evans/close-issue@v3 + with: + comment: 请先尝试使用最新版本,如果问题依然存在再提交 issue \ No newline at end of file From 5a453567de2b9eca065331d91771a89f09041093 Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Sun, 7 Apr 2024 20:53:46 +0800 Subject: [PATCH 04/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.idea/.gitignore b/.idea/.gitignore index ef28b4af..b4f617f7 100644 --- a/.idea/.gitignore +++ b/.idea/.gitignore @@ -11,3 +11,5 @@ /compiler.xml /inspectionProfiles/Project_Default.xml /CamelCaseConfigNew.xml +# GitHub Copilot persisted chat sessions +/copilot/chatSessions From 81802754fa5bd3cd1852c6769c9c09a586d0655c Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Mon, 8 Apr 2024 20:20:36 +0800 Subject: [PATCH 05/19] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E5=99=A8=E4=BF=A1=E6=81=AF=E6=9F=A5=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 5 + .../activities/settings/MediaCodecActivity.kt | 18 + .../bv/screen/settings/MediaCodecScreen.kt | 427 ++++++++++++++++++ .../bv/screen/settings/content/InfoSetting.kt | 8 + .../dev/aaa1115910/bv/util/CodecUtil.kt | 170 +++++++ app/src/main/res/values/strings.xml | 21 + 6 files changed, 649 insertions(+) create mode 100644 app/src/main/kotlin/dev/aaa1115910/bv/activities/settings/MediaCodecActivity.kt create mode 100644 app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/MediaCodecScreen.kt create mode 100644 app/src/main/kotlin/dev/aaa1115910/bv/util/CodecUtil.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 28881b49..632bab84 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -41,6 +41,11 @@ android:exported="true" android:label="@string/title_activity_user_switch" android:theme="@style/Theme.BV" /> + (null) } + var focusInNav by remember { mutableStateOf(false) } + + val decoderList = remember { mutableStateListOf() } + + LaunchedEffect(Unit) { + val list = CodecUtil.parseCodecs().filter { it.type == CodecType.Decoder } + decoderList.swapList(list) + currentCodecInfoData = list[0] + } + + Scaffold( + modifier = modifier, + topBar = { + Box( + modifier = Modifier.padding( + start = 48.dp, + top = 24.dp, + bottom = 8.dp, + end = 48.dp + ) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.Bottom, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = stringResource(R.string.title_activity_media_codec), + fontSize = titleFontSize.sp + ) + Text( + text = "", + color = Color.White.copy(alpha = 0.6f) + ) + } + } + } + ) { innerPadding -> + Row( + modifier = Modifier.padding(innerPadding) + ) { + MediaCodecListItems( + modifier = Modifier + .onFocusChanged { focusInNav = it.hasFocus } + .weight(3f) + .fillMaxHeight(), + codecInfoDataList = decoderList, + currentCodecInfoData = currentCodecInfoData, + onCodecInfoDataChanged = { currentCodecInfoData = it }, + isFocusing = focusInNav + ) + MediaCodecDetails( + modifier = Modifier + .weight(5f) + .fillMaxSize(), + onBackNav = { focusInNav = true }, + currentCodecInfoData = currentCodecInfoData + ) + } + } +} + +@Composable +fun MediaCodecListItems( + modifier: Modifier = Modifier, + codecInfoDataList: List, + currentCodecInfoData: CodecInfoData?, + onCodecInfoDataChanged: (CodecInfoData) -> Unit, + isFocusing: Boolean +) { + val scope = rememberCoroutineScope() + val focusRequester = remember { FocusRequester() } + + LaunchedEffect(isFocusing) { + if (isFocusing) focusRequester.requestFocus(scope) + } + + LaunchedEffect(codecInfoDataList) { + focusRequester.requestFocus(scope) + } + + TvLazyColumn( + modifier = modifier, + contentPadding = PaddingValues(24.dp), + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + items(items = codecInfoDataList) { codecInfoData -> + val buttonModifier = if (currentCodecInfoData == codecInfoData) Modifier + .focusRequester(focusRequester) + .fillMaxWidth() + else Modifier.fillMaxWidth() + MediaCodecListItem( + modifier = buttonModifier, + codecInfoData = codecInfoData, + onFocus = { onCodecInfoDataChanged(codecInfoData) }, + selected = currentCodecInfoData == codecInfoData + ) + } + } +} + +@OptIn(ExperimentalTvMaterial3Api::class) +@Composable +fun MediaCodecListItem( + modifier: Modifier = Modifier, + codecInfoData: CodecInfoData, + onFocus: () -> Unit, + onLoseFocus: () -> Unit = {}, + onClick: () -> Unit = {}, + selected: Boolean +) { + ListItem( + modifier = modifier + .onFocusChanged { if (it.hasFocus) onFocus() else onLoseFocus() }, + selected = selected, + onClick = onClick, + headlineContent = { + Text( + modifier = Modifier.padding(horizontal = 16.dp), + text = codecInfoData.name, + //style = MaterialTheme.typography.titleLarge + ) + }, + overlineContent = { + Row( + modifier = Modifier.padding(horizontal = 16.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + Text( + modifier = Modifier + .clip(MaterialTheme.shapes.small) + .background(MaterialTheme.colorScheme.surfaceVariant) + .padding(horizontal = 8.dp), + text = codecInfoData.mimeType, + style = MaterialTheme.typography.titleMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + Icon( + imageVector = when (codecInfoData.media) { + CodecMedia.Audio -> Icons.Default.Audiotrack + CodecMedia.Video -> Icons.Default.Videocam + }, contentDescription = null + ) + } + } + ) +} + +@OptIn(ExperimentalTvMaterial3Api::class) +@Composable +fun MediaCodecDetails( + modifier: Modifier = Modifier, + onBackNav: () -> Unit, + currentCodecInfoData: CodecInfoData? +) { + val context = LocalContext.current + + if (currentCodecInfoData != null) { + TvLazyColumn( + modifier = modifier + .fillMaxSize() + .onPreviewKeyEvent { + val result = it.key.nativeKeyCode == android.view.KeyEvent.KEYCODE_DPAD_LEFT + if (result) onBackNav() + result + }, + verticalArrangement = Arrangement.spacedBy(12.dp), + contentPadding = PaddingValues( + horizontal = 48.dp, + vertical = 24.dp + ) + ) { + item { + MediaCodecDetailItem( + title = stringResource(R.string.codec_detail_hs_title), + text = when (currentCodecInfoData.mode) { + CodecMode.Hardware -> stringResource(R.string.codec_detail_hs_hardware) + CodecMode.Software -> stringResource(R.string.codec_detail_hs_software) + } + ) + } + item { + MediaCodecDetailItem( + title = stringResource(R.string.codec_detail_max_supported_instances_title), + text = currentCodecInfoData.maxSupportedInstances.toString() + ) + } + if (currentCodecInfoData.media == CodecMedia.Video) { + item { + MediaCodecDetailItem( + title = stringResource(R.string.codec_detail_color_formats_title), + text = currentCodecInfoData.colorFormats.joinToString() + ) + } + } + if (currentCodecInfoData.media == CodecMedia.Audio) { + item { + MediaCodecDetailItem( + title = stringResource(R.string.codec_detail_audio_bitrate_range_title), + text = "${currentCodecInfoData.audioBitrateRange?.first?.toBps()} - ${currentCodecInfoData.audioBitrateRange?.last?.toBps()}" + ) + } + } + if (currentCodecInfoData.media == CodecMedia.Video) { + item { + MediaCodecDetailItem( + title = stringResource(R.string.codec_detail_video_max_bitrate_title), + text = currentCodecInfoData.videoBitrateRange?.last?.toBps() ?: "Unknown" + ) + } + } + if (currentCodecInfoData.media == CodecMedia.Video) { + item { + MediaCodecDetailItem( + title = stringResource(R.string.codec_detail_video_frame_range_title), + text = "${currentCodecInfoData.videoFrame?.first}fps - ${currentCodecInfoData.videoFrame?.last}fps" + ) + } + } + if (currentCodecInfoData.media == CodecMedia.Video) { + item { + MediaCodecDetailItem( + title = stringResource(R.string.codec_detail_video_frame_supported_title), + text = currentCodecInfoData.supportedFrameRates.joinToString("\n") { supportedFrameRate -> + when (supportedFrameRate.resolution.second) { + 360 -> context.getString(R.string.codec_detail_video_resolution_360p) + 480 -> context.getString(R.string.codec_detail_video_resolution_480p) + 720 -> context.getString(R.string.codec_detail_video_resolution_720p) + 1080 -> context.getString(R.string.codec_detail_video_resolution_1080p) + 1440 -> context.getString(R.string.codec_detail_video_resolution_1440p) + 2160 -> context.getString(R.string.codec_detail_video_resolution_2160p) + 4320 -> context.getString(R.string.codec_detail_video_resolution_4320p) + else -> context.getString(R.string.codec_detail_video_resolution_unknown) + } + ": " + + ("${ + String.format( + Locale.getDefault(), + "%.1f", + supportedFrameRate.frameRate.upper + ) + }fps" + .takeUnless { supportedFrameRate.unsupported } + ?: context.getString(R.string.codec_detail_video_frame_unsupported)) + } + ) + } + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && currentCodecInfoData.media == CodecMedia.Video) { + item { + MediaCodecDetailItem( + title = stringResource(R.string.codec_detail_video_frame_achievable_title), + text = currentCodecInfoData.achievableFrameRates.joinToString("\n") { achievableFrameRates -> + when (achievableFrameRates.resolution.second) { + 360 -> context.getString(R.string.codec_detail_video_resolution_360p) + 480 -> context.getString(R.string.codec_detail_video_resolution_480p) + 720 -> context.getString(R.string.codec_detail_video_resolution_720p) + 1080 -> context.getString(R.string.codec_detail_video_resolution_1080p) + 1440 -> context.getString(R.string.codec_detail_video_resolution_1440p) + 2160 -> context.getString(R.string.codec_detail_video_resolution_2160p) + 4320 -> context.getString(R.string.codec_detail_video_resolution_4320p) + else -> context.getString(R.string.codec_detail_video_resolution_unknown) + } + ": " + + ("${ + String.format( + Locale.getDefault(), + "%.1f", + achievableFrameRates.frameRate.upper + ) + }fps" + .takeUnless { achievableFrameRates.unsupported } + ?: context.getString(R.string.codec_detail_video_frame_unsupported)) + } + ) + } + } + } + } else { + Box( + modifier = modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + Text("Empty") + } + } +} + +@OptIn(ExperimentalTvMaterial3Api::class) +@Composable +fun MediaCodecDetailItem( + modifier: Modifier = Modifier, + title: String, + text: String +) { + var hasFocus by remember { mutableStateOf(false) } + + ListItem( + modifier = modifier + .onFocusChanged { hasFocus = it.hasFocus }, + selected = hasFocus, + onClick = {}, + headlineContent = { Text(text = title) }, + supportingContent = { Text(text = text) } + ) +} + +private val previewCodecInfoData = CodecInfoData( + name = "c2.android.avc.decoder", + type = CodecType.Decoder, + mode = CodecMode.Hardware, + media = CodecMedia.Video, + mimeType = "video/avc", + maxSupportedInstances = 1, + colorFormats = listOf(21, 19, 20), + audioBitrateRange = 0..0, + videoBitrateRange = 0..0, + videoFrame = 0..0, + supportedFrameRates = emptyList(), + achievableFrameRates = emptyList() +) + +@Preview(device = "id:tv_1080p") +@Composable +private fun MediaCodecListItemPreview() { + BVTheme { + MediaCodecListItem( + codecInfoData = previewCodecInfoData, + onFocus = {}, + selected = false + ) + } +} + +@Preview(device = "id:tv_1080p") +@Composable +private fun MediaCodecDetailsPreview() { + BVTheme { + MediaCodecDetails( + currentCodecInfoData = previewCodecInfoData, + onBackNav = {} + ) + } +} + +private fun Int.toBps(): String { + return when { + this >= 1000000 -> "${this / 1000000} Mbps" + this >= 1000 -> "${this / 1000} Kbps" + else -> "$this bps" + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/content/InfoSetting.kt b/app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/content/InfoSetting.kt index 94f51f13..52053229 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/content/InfoSetting.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/content/InfoSetting.kt @@ -3,6 +3,7 @@ package dev.aaa1115910.bv.screen.settings.content import android.app.Activity import android.app.ActivityManager import android.content.Context +import android.content.Intent import android.os.Build import android.os.Environment import android.os.StatFs @@ -20,10 +21,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import androidx.tv.material3.Button import androidx.tv.material3.ExperimentalTvMaterial3Api import androidx.tv.material3.MaterialTheme import androidx.tv.material3.Text import dev.aaa1115910.bv.R +import dev.aaa1115910.bv.activities.settings.MediaCodecActivity import dev.aaa1115910.bv.screen.settings.SettingsMenuNavItem import java.text.DecimalFormat import kotlin.math.pow @@ -132,5 +135,10 @@ fun InfoSetting( ) ) } + Button(onClick = { + context.startActivity(Intent(context, MediaCodecActivity::class.java)) + }) { + Text(stringResource(id = R.string.title_activity_media_codec)) + } } } \ No newline at end of file diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/util/CodecUtil.kt b/app/src/main/kotlin/dev/aaa1115910/bv/util/CodecUtil.kt new file mode 100644 index 00000000..98639093 --- /dev/null +++ b/app/src/main/kotlin/dev/aaa1115910/bv/util/CodecUtil.kt @@ -0,0 +1,170 @@ +package dev.aaa1115910.bv.util + +import android.media.MediaCodecInfo +import android.media.MediaCodecList +import android.os.Build +import android.util.Range +import androidx.annotation.RequiresApi +import androidx.core.util.toRange + +object CodecUtil { + fun parseCodecs(): List { + return MediaCodecList(MediaCodecList.ALL_CODECS) + .codecInfos.toList() + .map { CodecInfoData.fromCodecInfo(it) } + } +} + +data class CodecInfoData( + val name: String, + val mimeType: String, + val type: CodecType, + val mode: CodecMode, + val media: CodecMedia, + //val codecProvider: CodecProvider, + val maxSupportedInstances: Int?, + val colorFormats: List, + val audioBitrateRange: IntRange?, + val videoBitrateRange: IntRange?, + val videoFrame: IntRange?, + val supportedFrameRates: List, + val achievableFrameRates: List +) { + companion object { + fun fromCodecInfo(codecInfo: MediaCodecInfo): CodecInfoData { + val capabilities = codecInfo.getCapabilitiesForType(codecInfo.supportedTypes.first()) + return CodecInfoData( + name = codecInfo.name, + mimeType = capabilities.mimeType, + type = CodecType.fromMediaCodecInfo(codecInfo), + mode = CodecMode.fromMediaCodecInfo(codecInfo), + media = CodecMedia.fromMediaCodecInfo(codecInfo), + maxSupportedInstances = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) + capabilities.maxSupportedInstances else null, + colorFormats = capabilities.colorFormats.toList(), + audioBitrateRange = runCatching { with(capabilities.audioCapabilities.bitrateRange) { lower..upper } }.getOrNull(), + videoBitrateRange = runCatching { with(capabilities.videoCapabilities.bitrateRange) { lower..upper } }.getOrNull(), + videoFrame = runCatching { with(capabilities.videoCapabilities.supportedFrameRates) { lower..upper } }.getOrNull(), + supportedFrameRates = runCatching { codecInfo.getSupportedFrameRates() } + .getOrDefault(emptyList()), + achievableFrameRates = runCatching { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) codecInfo.getAchievableFrameRates() else emptyList() + }.getOrDefault(emptyList()) + ) + } + } +} + +enum class CodecType { + Encoder, + Decoder; + + companion object { + fun fromMediaCodecInfo(mediaCodecInfo: MediaCodecInfo): CodecType { + return if (mediaCodecInfo.isEncoder) Encoder else Decoder + } + + } +} + +enum class CodecMedia { + Audio, + Video; + + companion object { + fun fromMediaCodecInfo(mediaCodecInfo: MediaCodecInfo): CodecMedia { + return if (mediaCodecInfo.isAudioCodec()) Audio else Video + } + } +} + +enum class CodecMode { + Hardware, + Software; + + companion object { + fun fromMediaCodecInfo(mediaCodecInfo: MediaCodecInfo): CodecMode { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + return if (mediaCodecInfo.isSoftwareOnly) Software else Hardware + } + + if (mediaCodecInfo.isAudioCodec()) return Software + + val name = mediaCodecInfo.name + if (name.contains("omx.brcm.video", true) + && name.contains("hw", true) + ) return Hardware + if (name.startsWith("omx.marvell.video.hw", true)) return Hardware + if (name.startsWith("omx.intel.hw_vd", true)) return Hardware + if (name.startsWith("omx.qcom", true) && name.endsWith("hw")) return Hardware + if (name.startsWith("c2.vda.arc", true) + || name.startsWith("arc.") + ) return Hardware + + return if ( + name.startsWith("omx.google.", true) + || name.contains("ffmpeg", true) + || (name.startsWith("omx.sec.", true) && name.contains(".sw.", true)) + || name.equals("omx.qcom.video.decoder.hevcswvdec", true) + || name.startsWith("c2.android.", true) + || name.startsWith("c2.google.", true) + || name.startsWith("omx.sprd.soft.", true) + || name.startsWith("omx.avcodec.", true) + || name.startsWith("omx.pv", true) + || name.endsWith("sw", true) + || name.endsWith("sw.dec", true) + || name.endsWith("sw_vd", true) + || (!name.startsWith("omx.", true) && !name.startsWith("c2.", true)) + ) Software else Hardware + } + } +} + +private fun MediaCodecInfo.isAudioCodec(): Boolean { + return supportedTypes.joinToString().contains("audio") +} + +private val resolutions = mapOf( + 480 to 360, + 720 to 480, + 1280 to 720, + 1920 to 1080, + 2560 to 1440, + 3840 to 2160, + 7680 to 4320 +) + +data class SupportedFrameRate( + val resolution: Pair, + val frameRate: Range, + val unsupported: Boolean +) + +private fun MediaCodecInfo.getSupportedFrameRates(): List { + return resolutions.map { (width, height) -> + val frameRates = runCatching { + val videoCapabilities = getCapabilitiesForType(supportedTypes.first()).videoCapabilities + videoCapabilities.getSupportedFrameRatesFor(width, height) + }.getOrNull() + SupportedFrameRate( + resolution = width to height, + frameRate = frameRates ?: ((0.0..0.0).toRange()), + unsupported = frameRates == null + ) + } +} + +@RequiresApi(Build.VERSION_CODES.M) +private fun MediaCodecInfo.getAchievableFrameRates(): List { + return resolutions.map { (width, height) -> + val frameRates = runCatching { + val videoCapabilities = getCapabilitiesForType(supportedTypes.first()).videoCapabilities + videoCapabilities.getAchievableFrameRatesFor(width, height) + }.getOrNull() + SupportedFrameRate( + resolution = width to height, + frameRate = frameRates ?: ((0.0..0.0).toRange()), + unsupported = frameRates == null + ) + } +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c1dd677d..6c61c802 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -13,6 +13,26 @@ Dolby Atoms Hi-Res + 音频码率范围 + 颜色格式 + 硬解 + 软解 + 软硬解码 + 最大并发编解码器实例数量 + 可实现的视频帧率(可能无数据) + 视频帧率范围 + 支持的视频帧率 + 不受支持 + 最大视频码率 + 1080P + 2K + 4K + 360P + 8K + 480P + 720P + Unknown + 取消 确定 @@ -231,6 +251,7 @@ 历史记录 登录 日志列表 + 解码器信息 遥控板按键演示 搜索输入 搜索结果 From 30d773aae5ea273cab96794370d7781b03590c87 Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Mon, 8 Apr 2024 21:34:25 +0800 Subject: [PATCH 06/19] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BC=98=E5=85=88?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E5=AE=98=E6=96=B9=20cdn=20=E7=9A=84=E9=80=89?= =?UTF-8?q?=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resolves #109, resolves #130 --- .../screen/settings/content/NetworkSetting.kt | 13 ++++++++ .../kotlin/dev/aaa1115910/bv/util/Prefs.kt | 6 ++++ .../bv/viewmodel/VideoPlayerV3ViewModel.kt | 33 ++++++++++++++++++- app/src/main/res/values/strings.xml | 2 ++ .../repositories/VideoPlayRepositoryTest.kt | 25 ++++++++++++++ 5 files changed, 78 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/content/NetworkSetting.kt b/app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/content/NetworkSetting.kt index 7e728e50..12a498a2 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/content/NetworkSetting.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/content/NetworkSetting.kt @@ -53,6 +53,7 @@ fun NetworkSetting( var enableProxy by remember { mutableStateOf(Prefs.enableProxy) } var proxyHttpServer by remember { mutableStateOf(Prefs.proxyHttpServer) } var proxyGRPCServer by remember { mutableStateOf(Prefs.proxyGRPCServer) } + var preferOfficialCdn by remember { mutableStateOf(Prefs.preferOfficialCdn) } var showProxyHttpServerEditDialog by remember { mutableStateOf(false) } var showProxyGRPCServerEditDialog by remember { mutableStateOf(false) } @@ -108,6 +109,18 @@ fun NetworkSetting( } } + item { + SettingSwitchListItem( + title = stringResource(R.string.settings_network_prefer_official_cdn_title), + supportText = stringResource(R.string.settings_network_prefer_official_cdn_text), + checked = Prefs.preferOfficialCdn, + onCheckedChange = { enable -> + preferOfficialCdn = enable + Prefs.preferOfficialCdn = enable + } + ) + } + item { SettingListItem( title = stringResource(R.string.settings_network_test_title), diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/util/Prefs.kt b/app/src/main/kotlin/dev/aaa1115910/bv/util/Prefs.kt index 24c95821..d335dff1 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/util/Prefs.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/util/Prefs.kt @@ -274,6 +274,10 @@ object Prefs { set(value) = runBlocking { dsm.editPreference(PrefKeys.prefShowedRemoteControllerPanelDemoKey, value) } + + var preferOfficialCdn: Boolean + get() = runBlocking { dsm.getPreferenceFlow(PrefKeys.prefPreferOfficialCdnRequest).first() } + set(value) = runBlocking { dsm.editPreference(PrefKeys.prefPreferOfficialCdn, value) } } private object PrefKeys { @@ -315,6 +319,7 @@ private object PrefKeys { val prefProxyGRPCServerKey = stringPreferencesKey("proxy_grpc_server") val prefLastVersionCodeKey = intPreferencesKey("last_version_code") val prefShowedRemoteControllerPanelDemoKey = booleanPreferencesKey("showed_rcpd") + val prefPreferOfficialCdn = booleanPreferencesKey("prefer_official_cdn") val prefIsLoginRequest = PreferenceRequest(prefIsLoginKey, false) val prefUidRequest = PreferenceRequest(prefUidKey, 0) @@ -364,4 +369,5 @@ private object PrefKeys { val prefLastVersionCodeRequest = PreferenceRequest(prefLastVersionCodeKey, 0) val prefShowedRemoteControllerPanelDemoRequest = PreferenceRequest(prefShowedRemoteControllerPanelDemoKey, false) + val prefPreferOfficialCdnRequest = PreferenceRequest(prefPreferOfficialCdn, false) } \ No newline at end of file diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/VideoPlayerV3ViewModel.kt b/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/VideoPlayerV3ViewModel.kt index 49cb2955..36fca4f9 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/VideoPlayerV3ViewModel.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/VideoPlayerV3ViewModel.kt @@ -311,17 +311,30 @@ class VideoPlayerV3ViewModel( } } var videoUrl = videoItem?.baseUrl ?: playData!!.dashVideos.first().baseUrl + val videoUrls = mutableListOf() + videoUrls.add(videoItem?.baseUrl) + videoUrls.addAll(videoItem?.backUrl ?: emptyList()) val audioItem = playData!!.dashAudios.find { it.codecId == audio.code } ?: playData!!.dolby.takeIf { it?.codecId == audio.code } ?: playData!!.flac.takeIf { it?.codecId == audio.code } ?: playData!!.dashAudios.minByOrNull { it.codecId } var audioUrl = audioItem?.baseUrl ?: playData!!.dashAudios.first().baseUrl + val audioUrls = mutableListOf() + audioUrls.add(audioItem?.baseUrl) + audioUrls.addAll(audioItem?.backUrl ?: emptyList()) + + logger.fInfo { "all video hosts: ${videoUrls.map { with(URI(it)) { "$scheme://$authority" } }}" } + logger.fInfo { "all audio hosts: ${audioUrls.map { with(URI(it)) { "$scheme://$authority" } }}" } //replace cdn if (Prefs.enableProxy && proxyArea != ProxyArea.MainLand) { videoUrl = videoUrl.replaceUrlDomainWithAliCdn() audioUrl = audioUrl.replaceUrlDomainWithAliCdn() + } else { + // 如果未通过网络代理获得播放地址,才判断是否应该替换为官方 cdn + videoUrl = selectOfficialCdnUrl(videoUrls.filterNotNull()) + audioUrl = selectOfficialCdnUrl(audioUrls.filterNotNull()) } addLogs("video host: ${with(URI(videoUrl)) { "$scheme://$authority" }}") @@ -418,7 +431,7 @@ class VideoPlayerV3ViewModel( } private fun addLogs(text: String) { - println(text) + logger.fInfo { text } val lines = logs.lines().toMutableList() lines.add(text) while (lines.size > 8) { @@ -502,4 +515,22 @@ class VideoPlayerV3ViewModel( .build() .toString() } + + private fun selectOfficialCdnUrl(urls: List): String { + if (!Prefs.preferOfficialCdn) { + logger.fInfo { "doesn't need to filter official cdn url, select the first url" } + return urls.first() + } + val filteredUrls = urls + .filter { !it.contains(".mcdn.bilivideo.") } + .filter { !it.contains(".szbdyd.com") } + .filter { !Regex("""^https?://\d{1,3}.\d{1,3}""").matches(it) } + if (filteredUrls.isEmpty()) { + logger.fInfo { "doesn't find any official cdn url, select the first url" } + return urls.first() + } else { + logger.fInfo { "filtered official cdn urls: $filteredUrls" } + return filteredUrls.first() + } + } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6c61c802..b5202865 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -211,6 +211,8 @@ 界面设置 使用自定义代理服务器获取部分视频播放地址 启用代理 + 优先使用获取到的官方 CDN + P(M)CDN 快走开 gRPC 接口代理服务器 HTTP 接口代理服务器 未填写 diff --git a/bili-api/src/test/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepositoryTest.kt b/bili-api/src/test/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepositoryTest.kt index 4bf9a121..654e1c0e 100644 --- a/bili-api/src/test/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepositoryTest.kt +++ b/bili-api/src/test/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepositoryTest.kt @@ -8,6 +8,7 @@ import dev.aaa1115910.biliapi.http.BiliHttpProxyApi import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Test import java.io.File +import java.net.URL import java.nio.file.Paths import java.util.Properties import kotlin.io.encoding.Base64 @@ -299,5 +300,29 @@ class VideoPlayRepositoryTest { println("web result: $webResult") println("app result: $appResult") } + + @Test + fun `get play url domain`()= runBlocking { + val getUrlDomain:(String)->String={ + val url= URL(it) + "${url.protocol}://${url.host}" + } + ApiType.entries.forEach { apiType -> + val result = videoPlayRepository.getPlayData( + aid = 934637444, + cid = 455439756, + preferApiType = apiType + ) + println("api type: $apiType") + + result.dashVideos.forEach { video -> + println("video quality: ${video.quality}") + val videoUrls= mutableListOf() + videoUrls.add(video.baseUrl) + videoUrls.addAll(video.backUrl) + videoUrls.forEach { println(getUrlDomain(it)) } + } + } + } } From 204cfeadef8941cd8a0b248bd76f7c505d9dad11 Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Fri, 19 Apr 2024 20:48:13 +0800 Subject: [PATCH 07/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/kotlinc.xml | 2 +- bili-api-grpc/build.gradle.kts | 4 ++-- gradle/androidx.versions.toml | 16 ++++++++-------- gradle/gradle.versions.toml | 10 +++++----- gradle/libs.versions.toml | 20 ++++++++++---------- gradle/wrapper/gradle-wrapper.properties | 2 +- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index 8d81632f..fe63bb67 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/bili-api-grpc/build.gradle.kts b/bili-api-grpc/build.gradle.kts index 07430687..e6664765 100644 --- a/bili-api-grpc/build.gradle.kts +++ b/bili-api-grpc/build.gradle.kts @@ -46,10 +46,10 @@ protobuf { } it.plugins { create("grpc") { - option("lite") + //option("lite") } create("grpckt") { - option("lite") + //option("lite") } } } diff --git a/gradle/androidx.versions.toml b/gradle/androidx.versions.toml index d617c745..c3c86c08 100644 --- a/gradle/androidx.versions.toml +++ b/gradle/androidx.versions.toml @@ -1,17 +1,17 @@ [versions] -activity = "1.8.2" -compose = "1.5.4" -compose-compiler = "1.5.8" +activity = "1.9.0" +compose = "1.6.6" +compose-compiler = "1.5.12" compose-constraintlayout = "1.0.1" -compose-material3 = "1.2.0-beta02" +compose-material3 = "1.2.1" compose-tv = "1.0.0-alpha10" -core = "1.12.0" +core = "1.13.0" core-splashscreen = "1.0.1" -dataStore = "1.0.0" +dataStore = "1.1.0" lifecycle = "2.7.0" -media3 = "1.2.1" +media3 = "1.3.1" room = "2.6.1" -webkit = "1.9.0" +webkit = "1.10.0" [libraries] # https://developer.android.com/jetpack/androidx/releases/activity diff --git a/gradle/gradle.versions.toml b/gradle/gradle.versions.toml index d2b9f160..20108587 100644 --- a/gradle/gradle.versions.toml +++ b/gradle/gradle.versions.toml @@ -1,11 +1,11 @@ [versions] -agp = "8.2.1" +agp = "8.2.2" firebase-crashlytics = "2.9.9" -gms = "4.4.0" -kotlin = "1.9.22" -ksp = "1.9.22-1.0.17" +gms = "4.4.1" +kotlin = "1.9.23" +ksp = "1.9.23-1.0.19" protobuf = "0.9.4" -versions = "0.50.0" +versions = "0.51.0" [plugins] android-application = { id = "com.android.application", version.ref = "agp" } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9385b18b..ef97afed 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,20 +1,20 @@ [versions] akdanmaku = "1.0.3" -coil = "2.5.0" -firebase-bom = "32.7.1" +coil = "2.6.0" +firebase-bom = "32.8.1" geetest-sensebot = "4.4.2.1" -grpc = "1.60.0" +grpc = "1.63.0" grpc-kotlin = "1.4.1" jsoup = "1.17.2" -koin = "3.5.3" -koin-compose = "3.5.3" -kotlinx-coroutines = "1.7.3" -kotlinx-serialization = "1.6.2" -ktor = "2.3.7" +koin = "3.5.6" +koin-compose = "3.5.6" +kotlinx-coroutines = "1.8.0" +kotlinx-serialization = "1.6.3" +ktor = "2.3.10" ktor-jsoup = "2.3.0" -logging = "6.0.3" +logging = "6.0.9" material = "1.11.0" -protobuf = "3.25.2" +protobuf = "4.26.1" #noinspection GradleDependency 之后的版本要求 minSDK >= 23 qrcode = "3.3.0" rememberPreference = "1.0.2" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e9d77d87..bdb86fb3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Sun Nov 20 12:22:18 CST 2022 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From f0f5c8e7b1785d3b241d3fa083f33d5f307e5f34 Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Fri, 19 Apr 2024 20:57:36 +0800 Subject: [PATCH 08/19] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E8=A7=86=E9=A2=91=E6=8E=A8=E8=8D=90=E6=97=B6=E5=9B=A0=E5=8D=95?= =?UTF-8?q?=E6=AC=A1=E8=8E=B7=E5=BE=97=E7=9A=84=E8=A7=86=E9=A2=91=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E8=BF=87=E5=B0=91=E5=AF=BC=E8=87=B4=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E5=A1=AB=E5=85=85=E6=BB=A1=E5=B1=8F=E5=B9=95=EF=BC=88App?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aaa1115910/bv/viewmodel/home/RecommendViewModel.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/home/RecommendViewModel.kt b/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/home/RecommendViewModel.kt index 25372db8..b382724a 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/home/RecommendViewModel.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/home/RecommendViewModel.kt @@ -24,7 +24,15 @@ class RecommendViewModel( var loading = false suspend fun loadMore() { - if (!loading) loadData() + var loadCount = 0 + val maxLoadMoreCount = 3 + if (!loading) { + while (recommendVideoList.size < 14 && loadCount < maxLoadMoreCount) { + loadData() + if (loadCount != 0) logger.fInfo { "Load more recommend videos because items too less" } + loadCount++ + } + } } private suspend fun loadData() { From be113d8eff92e1446372613674943d80c2870d95 Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Fri, 19 Apr 2024 22:45:14 +0800 Subject: [PATCH 09/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20proguard-rules.pro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/proguard-rules.pro | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index f07a2b9f..a1df1f2e 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -96,4 +96,9 @@ # gRPC -keep class bilibili.rpc.** { *; } --keep class com.google.protobuf.** { *; } \ No newline at end of file +-keep class com.google.protobuf.** { *; } +-dontwarn com.google.protobuf.GeneratedMessageV3$Builder +-dontwarn com.google.protobuf.GeneratedMessageV3$BuilderParent +-dontwarn com.google.protobuf.GeneratedMessageV3$FieldAccessorTable +-dontwarn com.google.protobuf.GeneratedMessageV3 +-dontwarn com.google.protobuf.RepeatedFieldBuilderV3 \ No newline at end of file From cc5be7f34365c27670391498a7edf4c4bbe65aa3 Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Sun, 28 Apr 2024 23:39:29 +0800 Subject: [PATCH 10/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20Actions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 不再打包 abi 分包 - 不再上传至 MS AppCenter - 自动上传到 Github Release --- .github/workflows/alpha.yml | 292 +++++--------------------------- .github/workflows/features.yml | 139 +++------------ .github/workflows/release.yml | 297 +++++---------------------------- app/build.gradle.kts | 4 +- 4 files changed, 113 insertions(+), 619 deletions(-) diff --git a/.github/workflows/alpha.yml b/.github/workflows/alpha.yml index a9f4313a..9801c646 100644 --- a/.github/workflows/alpha.yml +++ b/.github/workflows/alpha.yml @@ -10,11 +10,6 @@ jobs: name: Build Alpha Apk runs-on: macos-latest if: github.repository == 'aaa1115910/bv' - outputs: - lite_alpha_info_apk_filename: ${{ steps.lite-info.outputs.lite_alpha_info_apk_filename }} - default_alpha_info_version_code: ${{ steps.default-info.outputs.default_alpha_info_version_code }} - default_alpha_info_version_name: ${{ steps.default-info.outputs.default_alpha_info_version_name }} - changelog: ${{ steps.changelog.outputs.changelog }} steps: - name: Checkout @@ -43,283 +38,82 @@ jobs: SIGNING_PROPERTIES: ${{ secrets.SIGNING_PROPERTIES }} run: | echo ${{ secrets.SIGNING_PROPERTIES }} > encoded_signing_properties - base64 -d encoded_signing_properties > signing.properties + base64 -Dd -i encoded_signing_properties > signing.properties - name: Add jks file run: | echo ${{ secrets.SIGN_KEY }} > ./encoded_key - base64 -d encoded_key > key.jks + base64 -Dd -i encoded_key > key.jks - - name: Build lite apk - run: ./gradlew assembleLiteAlpha assembleLiteDebug - - - name: Build default apk + - name: Build apk run: ./gradlew assembleDefaultAlpha assembleDefaultDebug - - name: Read lite alpha apk output metadata - id: apk-meta-lite-alpha - uses: juliangruber/read-file-action@v1 - with: - path: app/build/outputs/apk/lite/alpha/output-metadata.json - - - name: Read lite debug apk output metadata - id: apk-meta-lite-debug - uses: juliangruber/read-file-action@v1 - with: - path: app/build/outputs/apk/lite/debug/output-metadata.json - - - name: Read default alpha apk output metadata - id: apk-meta-default-alpha + - name: Read alpha apk output metadata + id: apk-meta-alpha uses: juliangruber/read-file-action@v1 with: path: app/build/outputs/apk/default/alpha/output-metadata.json - - name: Read default debug apk output metadata - id: apk-meta-default-debug + - name: Read alpha debug apk output metadata + id: apk-meta-alpha-debug uses: juliangruber/read-file-action@v1 with: path: app/build/outputs/apk/default/debug/output-metadata.json - - name: Parse lite apks info - id: lite-info + - name: Parse apk infos + id: apk-infos run: | - echo "lite_alpha_info_apk_filename=${{ fromJson(steps.apk-meta-lite-alpha.outputs.content).elements[0].outputFile }}" >> $GITHUB_ENV - echo "lite_debug_info_apk_filename=${{ fromJson(steps.apk-meta-lite-debug.outputs.content).elements[0].outputFile }}" >> $GITHUB_ENV - echo "lite_alpha_info_apk_filename=${{ fromJson(steps.apk-meta-lite-alpha.outputs.content).elements[0].outputFile }}" >> $GITHUB_OUTPUT + echo "alpha_info_version_code=${{ fromJson(steps.apk-meta-alpha.outputs.content).elements[0].versionCode }}" >> $GITHUB_ENV + echo "alpha_info_version_name=${{ fromJson(steps.apk-meta-alpha.outputs.content).elements[0].versionName }}" >> $GITHUB_ENV + echo "alpha_debug_info_version_code=${{ fromJson(steps.apk-meta-alpha-debug.outputs.content).elements[0].versionCode }}" >> $GITHUB_ENV + echo "alpha_debug_info_version_name=${{ fromJson(steps.apk-meta-alpha-debug.outputs.content).elements[0].versionName }}" >> $GITHUB_ENV - - name: Parse default apks info - id: default-info - run: | - echo "default_alpha_info_version_code=${{ fromJson(steps.apk-meta-default-alpha.outputs.content).elements[0].versionCode }}" >> $GITHUB_ENV - echo "default_alpha_info_version_name=${{ fromJson(steps.apk-meta-default-alpha.outputs.content).elements[0].versionName }}" >> $GITHUB_ENV - echo "default_debug_info_version_code=${{ fromJson(steps.apk-meta-default-debug.outputs.content).elements[0].versionCode }}" >> $GITHUB_ENV - echo "default_debug_info_version_name=${{ fromJson(steps.apk-meta-default-debug.outputs.content).elements[0].versionName }}" >> $GITHUB_ENV - echo "default_alpha_info_version_code=${{ fromJson(steps.apk-meta-default-alpha.outputs.content).elements[0].versionCode }}" >> $GITHUB_OUTPUT - echo "default_alpha_info_version_name=${{ fromJson(steps.apk-meta-default-alpha.outputs.content).elements[0].versionName }}" >> $GITHUB_OUTPUT + - name: Determine tag name + id: tag_name + run: echo "tag_name=alpha-r${{ env.alpha_info_version_code }}" >> $GITHUB_ENV - - name: Set changelog to output + - name: Get changelog id: changelog run: | - echo "changelog<> $GITHUB_OUTPUT - echo "$(git log -1 --pretty=short)" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - # upload artifacts lite-debug + { + echo "changelog<> "$GITHUB_ENV" - - name: Archive lite debug build artifacts - uses: actions/upload-artifact@v3 - with: - name: Lite debug build artifact - path: app/build/outputs/apk/lite/debug/${{ env.lite_debug_info_apk_filename }} - - # upload artifacts lite-alpha + # upload artifacts alpha debug - - name: Archive lite alpha build artifacts + - name: Archive alpha debug build artifacts uses: actions/upload-artifact@v3 with: - name: Lite alpha build artifact - path: app/build/outputs/apk/lite/alpha/${{ env.lite_alpha_info_apk_filename }} + name: Alpha debug build artifact + path: app/build/outputs/apk/default/debug/BV_${{ env.alpha_debug_info_version_code }}_${{ env.alpha_debug_info_version_name }}_default_universal.apk - - name: Archive lite alpha build mappings - uses: actions/upload-artifact@v3 - with: - name: Lite alpha build mappings - path: app/build/outputs/mapping/liteAlpha - - # upload artifacts default-debug - - - name: Archive default debug build artifacts (universal) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (universal) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_universal.apk - - - name: Archive default debug build artifacts (armeabi-v7a) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (armeabi-v7a) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_armeabi-v7a.apk - - - name: Archive default debug build artifacts (arm64-v8a) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (arm64-v8a) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_arm64-v8a.apk - - - name: Archive default debug build artifacts (x86) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (x86) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_x86.apk - - - name: Archive default debug build artifacts (x86_64) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (x86_64) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_x86_64.apk - - # upload artifacts default-alpha + # upload artifacts alpha - name: Archive default alpha build mappings uses: actions/upload-artifact@v3 with: - name: Default alpha build mappings + name: Alpha build mappings path: app/build/outputs/mapping/defaultAlpha - - name: Archive default alpha build artifacts (universal) + - name: Archive alpha build artifacts uses: actions/upload-artifact@v3 with: - name: Default alpha build artifact (universal) - path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_universal.apk + name: Alpha build artifact + path: app/build/outputs/apk/default/alpha/BV_${{ env.alpha_info_version_code }}_${{ env.alpha_info_version_name }}_default_universal.apk - - name: Archive default alpha build artifacts (armeabi-v7a) - uses: actions/upload-artifact@v3 - with: - name: Default alpha build artifact (armeabi-v7a) - path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_armeabi-v7a.apk - - - name: Archive default alpha build artifacts (arm64-v8a) - uses: actions/upload-artifact@v3 - with: - name: Default alpha build artifact (arm64-v8a) - path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_arm64-v8a.apk - - - name: Archive default alpha build artifacts (x86) - uses: actions/upload-artifact@v3 - with: - name: Default alpha build artifact (x86) - path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_x86.apk - - - name: Archive default alpha build artifacts (x86_64) - uses: actions/upload-artifact@v3 - with: - name: Default alpha build artifact (x86_64) - path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_x86_64.apk - - upload-alpha: - name: Upload Alpha Apk to App Center - needs: build-alpha - runs-on: ubuntu-latest - - steps: - # download artifacts - - - name: download lite alpha build artifacts - uses: actions/download-artifact@v3 - with: - name: Lite alpha build artifact - - - name: download default alpha build artifacts (universal) - uses: actions/download-artifact@v3 - with: - name: Default alpha build artifact (universal) - - - name: download default alpha build artifacts (armeabi-v7a) - uses: actions/download-artifact@v3 - with: - name: Default alpha build artifact (armeabi-v7a) - - - name: download default alpha build artifacts (arm64-v8a) - uses: actions/download-artifact@v3 - with: - name: Default alpha build artifact (arm64-v8a) - - - name: download default alpha build artifacts (x86) - uses: actions/download-artifact@v3 - with: - name: Default alpha build artifact (x86) - - - name: download default alpha build artifacts (x86_64) - uses: actions/download-artifact@v3 - with: - name: Default alpha build artifact (x86_64) - - # upload to app center - - - name: Setup app center cli - id: setup-appcenter-cli - run: npm install -g appcenter-cli - - - name: Upload lite alpha apk to app center - id: upload-lite-alpha-apk - uses: nick-fields/retry@v2 - with: - timeout_minutes: 1 - max_attempts: 5 - command: | - appcenter distribute release \ - --app aaa1115910-gmail.com/BV \ - --file ${{ needs.build-alpha.outputs.lite_alpha_info_apk_filename }} \ - --group Alpha \ - --token ${{ secrets.APP_CENTER_TOKEN }} \ - --release-notes "${{ needs.build-alpha.outputs.changelog }}" - - - name: Upload default alpha apk to app center (universal) - id: upload-default-alpha-apk-universal - uses: nick-fields/retry@v2 - with: - timeout_minutes: 1 - max_attempts: 5 - command: | - appcenter distribute release \ - --app aaa1115910-gmail.com/BV \ - --file BV_${{ needs.build-alpha.outputs.default_alpha_info_version_code }}_${{ needs.build-alpha.outputs.default_alpha_info_version_name }}_default_universal.apk \ - --group Alpha-universal \ - --token ${{ secrets.APP_CENTER_TOKEN }} \ - --release-notes "${{ needs.build-alpha.outputs.changelog }}" - - - name: Upload default alpha apk to app center (armeabi-v7a) - id: upload-default-alpha-apk-armeabi-v7a - uses: nick-fields/retry@v2 - with: - timeout_minutes: 1 - max_attempts: 5 - command: | - appcenter distribute release \ - --app aaa1115910-gmail.com/BV \ - --file BV_${{ needs.build-alpha.outputs.default_alpha_info_version_code }}_${{ needs.build-alpha.outputs.default_alpha_info_version_name }}_default_armeabi-v7a.apk \ - --group Alpha-armeabi-v7a \ - --token ${{ secrets.APP_CENTER_TOKEN }} \ - --release-notes "${{ needs.build-alpha.outputs.changelog }}" - - - name: Upload default alpha apk to app center (arm64-v8a) - id: upload-default-alpha-apk-arm64-v8a - uses: nick-fields/retry@v2 - with: - timeout_minutes: 1 - max_attempts: 5 - command: | - appcenter distribute release \ - --app aaa1115910-gmail.com/BV \ - --file BV_${{ needs.build-alpha.outputs.default_alpha_info_version_code }}_${{ needs.build-alpha.outputs.default_alpha_info_version_name }}_default_arm64-v8a.apk \ - --group Alpha-arm64-v8a \ - --token ${{ secrets.APP_CENTER_TOKEN }} \ - --release-notes "${{ needs.build-alpha.outputs.changelog }}" - - - name: Upload default alpha apk to app center (x86) - id: upload-default-alpha-apk-x86 - uses: nick-fields/retry@v2 - with: - timeout_minutes: 1 - max_attempts: 5 - command: | - appcenter distribute release \ - --app aaa1115910-gmail.com/BV \ - --file BV_${{ needs.build-alpha.outputs.default_alpha_info_version_code }}_${{ needs.build-alpha.outputs.default_alpha_info_version_name }}_default_x86.apk \ - --group Alpha-x86 \ - --token ${{ secrets.APP_CENTER_TOKEN }} \ - --release-notes "${{ needs.build-alpha.outputs.changelog }}" + # upload to github release - - name: Upload default alpha apk to app center (x86_64) - id: upload-default-alpha-apk-x86_64 - uses: nick-fields/retry@v2 + - name: Publish Pre-Release + uses: softprops/action-gh-release@v2 with: - timeout_minutes: 1 - max_attempts: 5 - command: | - appcenter distribute release \ - --app aaa1115910-gmail.com/BV \ - --file BV_${{ needs.build-alpha.outputs.default_alpha_info_version_code }}_${{ needs.build-alpha.outputs.default_alpha_info_version_name }}_default_x86_64.apk \ - --group Alpha-x86_64 \ - --token ${{ secrets.APP_CENTER_TOKEN }} \ - --release-notes "${{ needs.build-alpha.outputs.changelog }}" \ No newline at end of file + files: | + app/build/outputs/apk/default/debug/BV_${{ env.alpha_debug_info_version_code }}_${{ env.alpha_debug_info_version_name }}_default_universal.apk + app/build/outputs/apk/default/alpha/BV_${{ env.alpha_info_version_code }}_${{ env.alpha_info_version_name }}_default_universal.apk + app/build/outputs/mapping/defaultAlpha + tag_name: ${{ env.tag_name }} + name: ${{ env.alpha_info_version_name }} + prerelease: true + body: ${{ env.changelog }} + target_commitish: ${{ github.sha }} diff --git a/.github/workflows/features.yml b/.github/workflows/features.yml index ba2a10fb..6e258a7e 100644 --- a/.github/workflows/features.yml +++ b/.github/workflows/features.yml @@ -10,6 +10,7 @@ jobs: name: Build Feature Apk runs-on: macos-latest if: github.repository == 'aaa1115910/bv' + steps: - name: Checkout uses: actions/checkout@v3 @@ -37,146 +38,54 @@ jobs: SIGNING_PROPERTIES: ${{ secrets.SIGNING_PROPERTIES }} run: | echo ${{ secrets.SIGNING_PROPERTIES }} > encoded_signing_properties - base64 -d encoded_signing_properties > signing.properties + base64 -Dd -i encoded_signing_properties > signing.properties - name: Add jks file run: | echo ${{ secrets.SIGN_KEY }} > ./encoded_key - base64 -d encoded_key > key.jks - - - name: Build lite apk - run: ./gradlew assembleLiteAlpha assembleLiteDebug + base64 -Dd -i encoded_key > key.jks - - name: Build default apk + - name: Build apk run: ./gradlew assembleDefaultAlpha assembleDefaultDebug - - name: Read lite alpha apk output metadata - id: apk-meta-lite-alpha - uses: juliangruber/read-file-action@v1 - with: - path: app/build/outputs/apk/lite/alpha/output-metadata.json - - - name: Read lite debug apk output metadata - id: apk-meta-lite-debug - uses: juliangruber/read-file-action@v1 - with: - path: app/build/outputs/apk/lite/debug/output-metadata.json - - - name: Read default alpha apk output metadata - id: apk-meta-default-alpha + - name: Read alpha apk output metadata + id: apk-meta-alpha uses: juliangruber/read-file-action@v1 with: path: app/build/outputs/apk/default/alpha/output-metadata.json - - name: Read default debug apk output metadata - id: apk-meta-default-debug + - name: Read alpha debug apk output metadata + id: apk-meta-alpha-debug uses: juliangruber/read-file-action@v1 with: path: app/build/outputs/apk/default/debug/output-metadata.json - - name: Parse lite apks info - id: lite-info - run: | - echo "lite_alpha_info_apk_filename=${{ fromJson(steps.apk-meta-lite-alpha.outputs.content).elements[0].outputFile }}" >> $GITHUB_ENV - echo "lite_debug_info_apk_filename=${{ fromJson(steps.apk-meta-lite-debug.outputs.content).elements[0].outputFile }}" >> $GITHUB_ENV - - - name: Parse default apks info - id: default-info + - name: Parse apk infos + id: apk-infos run: | - echo "default_alpha_info_version_code=${{ fromJson(steps.apk-meta-default-alpha.outputs.content).elements[0].versionCode }}" >> $GITHUB_ENV - echo "default_alpha_info_version_name=${{ fromJson(steps.apk-meta-default-alpha.outputs.content).elements[0].versionName }}" >> $GITHUB_ENV - echo "default_debug_info_version_code=${{ fromJson(steps.apk-meta-default-debug.outputs.content).elements[0].versionCode }}" >> $GITHUB_ENV - echo "default_debug_info_version_name=${{ fromJson(steps.apk-meta-default-debug.outputs.content).elements[0].versionName }}" >> $GITHUB_ENV - - # upload artifacts lite-debug - - - name: Archive lite debug build artifacts - uses: actions/upload-artifact@v3 - with: - name: Lite debug build artifact - path: app/build/outputs/apk/lite/debug/${{ env.lite_debug_info_apk_filename }} - - # upload artifacts lite-alpha - - - name: Archive lite alpha build artifacts - uses: actions/upload-artifact@v3 - with: - name: Lite alpha build artifact - path: app/build/outputs/apk/lite/alpha/${{ env.lite_alpha_info_apk_filename }} - - - name: Archive lite alpha build mappings - uses: actions/upload-artifact@v3 - with: - name: Lite alpha build mappings - path: app/build/outputs/mapping/liteAlpha - - # upload artifacts default-debug - - - name: Archive default debug build artifacts (universal) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (universal) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_universal.apk - - - name: Archive default debug build artifacts (armeabi-v7a) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (armeabi-v7a) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_armeabi-v7a.apk - - - name: Archive default debug build artifacts (arm64-v8a) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (arm64-v8a) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_arm64-v8a.apk + echo "alpha_info_version_code=${{ fromJson(steps.apk-meta-alpha.outputs.content).elements[0].versionCode }}" >> $GITHUB_ENV + echo "alpha_info_version_name=${{ fromJson(steps.apk-meta-alpha.outputs.content).elements[0].versionName }}" >> $GITHUB_ENV + echo "alpha_debug_info_version_code=${{ fromJson(steps.apk-meta-alpha-debug.outputs.content).elements[0].versionCode }}" >> $GITHUB_ENV + echo "alpha_debug_info_version_name=${{ fromJson(steps.apk-meta-alpha-debug.outputs.content).elements[0].versionName }}" >> $GITHUB_ENV - - name: Archive default debug build artifacts (x86) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (x86) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_x86.apk + # upload artifacts alpha debug - - name: Archive default debug build artifacts (x86_64) + - name: Archive alpha debug build artifacts uses: actions/upload-artifact@v3 with: - name: Default debug build artifact (x86_64) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_x86_64.apk + name: Alpha debug build artifact + path: app/build/outputs/apk/default/debug/BV_${{ env.alpha_debug_info_version_code }}_${{ env.alpha_debug_info_version_name }}_default_universal.apk - # upload artifacts default-alpha + # upload artifacts alpha - - name: Archive default alpha build mappings + - name: Archive alpha build mappings uses: actions/upload-artifact@v3 with: - name: Default alpha build mappings + name: Alpha build mappings path: app/build/outputs/mapping/defaultAlpha - - name: Archive default alpha build artifacts (universal) + - name: Archive alpha build artifacts uses: actions/upload-artifact@v3 with: - name: Default alpha build artifact (universal) - path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_universal.apk - - - name: Archive default alpha build artifacts (armeabi-v7a) - uses: actions/upload-artifact@v3 - with: - name: Default alpha build artifact (armeabi-v7a) - path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_armeabi-v7a.apk - - - name: Archive default alpha build artifacts (arm64-v8a) - uses: actions/upload-artifact@v3 - with: - name: Default alpha build artifact (arm64-v8a) - path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_arm64-v8a.apk - - - name: Archive default alpha build artifacts (x86) - uses: actions/upload-artifact@v3 - with: - name: Default alpha build artifact (x86) - path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_x86.apk - - - name: Archive default alpha build artifacts (x86_64) - uses: actions/upload-artifact@v3 - with: - name: Default alpha build artifact (x86_64) - path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_x86_64.apk - + name: Alpha build artifact + path: app/build/outputs/apk/default/alpha/BV_${{ env.alpha_info_version_code }}_${{ env.alpha_info_version_name }}_default_universal.apk diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 36d95ef3..9d359ec5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,19 +2,15 @@ name: Release Build on: push: - branches: - - master + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + - 'v[0-9]+.[0-9]+.[0-9]+.[0-9]+' jobs: build-release: name: Build Release Apk runs-on: macos-latest if: github.repository == 'aaa1115910/bv' - outputs: - lite_release_info_apk_filename: ${{ steps.lite-info.outputs.lite_release_info_apk_filename }} - default_release_info_version_code: ${{ steps.default-info.outputs.default_release_info_version_code }} - default_release_info_version_name: ${{ steps.default-info.outputs.default_release_info_version_name }} - changelog: ${{ steps.changelog.outputs.changelog }} steps: - name: Checkout @@ -43,283 +39,78 @@ jobs: SIGNING_PROPERTIES: ${{ secrets.SIGNING_PROPERTIES }} run: | echo ${{ secrets.SIGNING_PROPERTIES }} > encoded_signing_properties - base64 -d encoded_signing_properties > signing.properties + base64 -Dd -i encoded_signing_properties > signing.properties - name: Add jks file run: | echo ${{ secrets.SIGN_KEY }} > ./encoded_key - base64 -d encoded_key > key.jks + base64 -Dd -i encoded_key > key.jks - - name: Build lite apk - run: ./gradlew assembleLiteRelease assembleLiteDebug - - - name: Build default apk + - name: Build apk run: ./gradlew assembleDefaultRelease assembleDefaultDebug - - name: Read lite release apk output metadata - id: apk-meta-lite-release - uses: juliangruber/read-file-action@v1 - with: - path: app/build/outputs/apk/lite/release/output-metadata.json - - - name: Read lite debug apk output metadata - id: apk-meta-lite-debug - uses: juliangruber/read-file-action@v1 - with: - path: app/build/outputs/apk/lite/debug/output-metadata.json - - - name: Read default release apk output metadata - id: apk-meta-default-release + - name: Read release apk output metadata + id: apk-meta-release uses: juliangruber/read-file-action@v1 with: path: app/build/outputs/apk/default/release/output-metadata.json - - name: Read default debug apk output metadata - id: apk-meta-default-debug + - name: Read debug apk output metadata + id: apk-meta-release-debug uses: juliangruber/read-file-action@v1 with: path: app/build/outputs/apk/default/debug/output-metadata.json - - name: Parse lite apks info - id: lite-info - run: | - echo "lite_release_info_apk_filename=${{ fromJson(steps.apk-meta-lite-release.outputs.content).elements[0].outputFile }}" >> $GITHUB_ENV - echo "lite_debug_info_apk_filename=${{ fromJson(steps.apk-meta-lite-debug.outputs.content).elements[0].outputFile }}" >> $GITHUB_ENV - echo "lite_release_info_apk_filename=${{ fromJson(steps.apk-meta-lite-release.outputs.content).elements[0].outputFile }}" >> $GITHUB_OUTPUT - - - name: Parse default apks info - id: default-info + - name: Parse apk infos + id: apk-infos run: | - echo "default_release_info_version_code=${{ fromJson(steps.apk-meta-default-release.outputs.content).elements[0].versionCode }}" >> $GITHUB_ENV - echo "default_release_info_version_name=${{ fromJson(steps.apk-meta-default-release.outputs.content).elements[0].versionName }}" >> $GITHUB_ENV - echo "default_debug_info_version_code=${{ fromJson(steps.apk-meta-default-debug.outputs.content).elements[0].versionCode }}" >> $GITHUB_ENV - echo "default_debug_info_version_name=${{ fromJson(steps.apk-meta-default-debug.outputs.content).elements[0].versionName }}" >> $GITHUB_ENV - echo "default_release_info_version_code=${{ fromJson(steps.apk-meta-default-release.outputs.content).elements[0].versionCode }}" >> $GITHUB_OUTPUT - echo "default_release_info_version_name=${{ fromJson(steps.apk-meta-default-release.outputs.content).elements[0].versionName }}" >> $GITHUB_OUTPUT + echo "release_info_version_code=${{ fromJson(steps.apk-meta-release.outputs.content).elements[0].versionCode }}" >> $GITHUB_ENV + echo "release_info_version_name=${{ fromJson(steps.apk-meta-release.outputs.content).elements[0].versionName }}" >> $GITHUB_ENV + echo "release_debug_info_version_code=${{ fromJson(steps.apk-meta-release-debug.outputs.content).elements[0].versionCode }}" >> $GITHUB_ENV + echo "release_debug_info_version_name=${{ fromJson(steps.apk-meta-release-debug.outputs.content).elements[0].versionName }}" >> $GITHUB_ENV - - name: Set changelog to output + - name: Get changelog id: changelog run: | - echo "changelog<> $GITHUB_OUTPUT - echo "$(git log -1 --pretty=short)" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT + { + echo "changelog<> "$GITHUB_ENV" - # upload artifacts lite-debug + # upload artifacts release debug - - name: Archive lite debug build artifacts + - name: Archive release debug build artifacts uses: actions/upload-artifact@v3 with: - name: Lite debug build artifact - path: app/build/outputs/apk/lite/debug/${{ env.lite_debug_info_apk_filename }} + name: Release debug build artifact + path: app/build/outputs/apk/default/debug/BV_${{ env.release_debug_info_version_code }}_${{ env.release_debug_info_version_name }}_default_universal.apk - # upload artifacts lite-release + # upload artifacts release - - name: Archive lite release build artifacts + - name: Archive release build mappings uses: actions/upload-artifact@v3 with: - name: Lite release build artifact - path: app/build/outputs/apk/lite/release/${{ env.lite_release_info_apk_filename }} - - - name: Archive lite alpha build mappings - uses: actions/upload-artifact@v3 - with: - name: Lite release build mappings - path: app/build/outputs/mapping/liteRelease - - # upload artifacts default-debug - - - name: Archive default debug build artifacts (universal) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (universal) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_universal.apk - - - name: Archive default debug build artifacts (armeabi-v7a) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (armeabi-v7a) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_armeabi-v7a.apk - - - name: Archive default debug build artifacts (arm64-v8a) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (arm64-v8a) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_arm64-v8a.apk - - - name: Archive default debug build artifacts (x86) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (x86) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_x86.apk - - - name: Archive default debug build artifacts (x86_64) - uses: actions/upload-artifact@v3 - with: - name: Default debug build artifact (x86_64) - path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_x86_64.apk - - # upload artifacts default-release - - - name: Archive default release build mappings - uses: actions/upload-artifact@v3 - with: - name: Default release build mappings + name: Release build mappings path: app/build/outputs/mapping/defaultRelease - - name: Archive default release build artifacts (universal) - uses: actions/upload-artifact@v3 - with: - name: Default release build artifact (universal) - path: app/build/outputs/apk/default/release/BV_${{ env.default_release_info_version_code }}_${{ env.default_release_info_version_name }}_default_universal.apk - - - name: Archive default release build artifacts (armeabi-v7a) + - name: Archive release build artifacts uses: actions/upload-artifact@v3 with: - name: Default release build artifact (armeabi-v7a) - path: app/build/outputs/apk/default/release/BV_${{ env.default_release_info_version_code }}_${{ env.default_release_info_version_name }}_default_armeabi-v7a.apk + name: Release build artifact + path: app/build/outputs/apk/default/release/BV_${{ env.release_info_version_code }}_${{ env.release_info_version_name }}_default_universal.apk - - name: Archive default release build artifacts (arm64-v8a) - uses: actions/upload-artifact@v3 - with: - name: Default release build artifact (arm64-v8a) - path: app/build/outputs/apk/default/release/BV_${{ env.default_release_info_version_code }}_${{ env.default_release_info_version_name }}_default_arm64-v8a.apk - - - name: Archive default release build artifacts (x86) - uses: actions/upload-artifact@v3 - with: - name: Default release build artifact (x86) - path: app/build/outputs/apk/default/release/BV_${{ env.default_release_info_version_code }}_${{ env.default_release_info_version_name }}_default_x86.apk - - - name: Archive default release build artifacts (x86_64) - uses: actions/upload-artifact@v3 - with: - name: Default release build artifact (x86_64) - path: app/build/outputs/apk/default/release/BV_${{ env.default_release_info_version_code }}_${{ env.default_release_info_version_name }}_default_x86_64.apk - - upload-release: - name: Upload Release Apk to App Center - needs: build-release - runs-on: ubuntu-latest - - steps: - # download artifacts - - - name: download lite release build artifacts - uses: actions/download-artifact@v3 - with: - name: Lite release build artifact - - - name: download default release build artifacts (universal) - uses: actions/download-artifact@v3 - with: - name: Default release build artifact (universal) - - - name: download default release build artifacts (armeabi-v7a) - uses: actions/download-artifact@v3 - with: - name: Default release build artifact (armeabi-v7a) - - - name: download default release build artifacts (arm64-v8a) - uses: actions/download-artifact@v3 - with: - name: Default release build artifact (arm64-v8a) - - - name: download default release build artifacts (x86) - uses: actions/download-artifact@v3 - with: - name: Default release build artifact (x86) - - - name: download default release build artifacts (x86_64) - uses: actions/download-artifact@v3 - with: - name: Default release build artifact (x86_64) - - # upload to app center - - - name: Setup app center cli - id: setup-appcenter-cli - run: npm install -g appcenter-cli - - - name: Upload lite release apk to app center - id: upload-lite-release-apk - uses: nick-fields/retry@v2 - with: - timeout_minutes: 1 - max_attempts: 5 - command: | - appcenter distribute release \ - --app aaa1115910-gmail.com/BV \ - --file ${{ needs.build-release.outputs.lite_release_info_apk_filename }} \ - --group Public \ - --token ${{ secrets.APP_CENTER_TOKEN }} \ - --release-notes "${{ needs.build-release.outputs.changelog }}" - - - name: Upload default release apk to app center (universal) - id: upload-default-release-apk-universal - uses: nick-fields/retry@v2 - with: - timeout_minutes: 1 - max_attempts: 5 - command: | - appcenter distribute release \ - --app aaa1115910-gmail.com/BV \ - --file BV_${{ needs.build-release.outputs.default_release_info_version_code }}_${{ needs.build-release.outputs.default_release_info_version_name }}_default_universal.apk \ - --group Public-universal \ - --token ${{ secrets.APP_CENTER_TOKEN }} \ - --release-notes "${{ needs.build-release.outputs.changelog }}" - - - name: Upload default release apk to app center (armeabi-v7a) - id: upload-default-release-apk-armeabi-v7a - uses: nick-fields/retry@v2 - with: - timeout_minutes: 1 - max_attempts: 5 - command: | - appcenter distribute release \ - --app aaa1115910-gmail.com/BV \ - --file BV_${{ needs.build-release.outputs.default_release_info_version_code }}_${{ needs.build-release.outputs.default_release_info_version_name }}_default_armeabi-v7a.apk \ - --group Public-armeabi-v7a \ - --token ${{ secrets.APP_CENTER_TOKEN }} \ - --release-notes "${{ needs.build-release.outputs.changelog }}" - - - name: Upload default release apk to app center (arm64-v8a) - id: upload-default-release-apk-arm64-v8a - uses: nick-fields/retry@v2 - with: - timeout_minutes: 1 - max_attempts: 5 - command: | - appcenter distribute release \ - --app aaa1115910-gmail.com/BV \ - --file BV_${{ needs.build-release.outputs.default_release_info_version_code }}_${{ needs.build-release.outputs.default_release_info_version_name }}_default_arm64-v8a.apk \ - --group Public-arm64-v8a \ - --token ${{ secrets.APP_CENTER_TOKEN }} \ - --release-notes "${{ needs.build-release.outputs.changelog }}" - - - name: Upload default release apk to app center (x86) - id: upload-default-release-apk-x86 - uses: nick-fields/retry@v2 - with: - timeout_minutes: 1 - max_attempts: 5 - command: | - appcenter distribute release \ - --app aaa1115910-gmail.com/BV \ - --file BV_${{ needs.build-release.outputs.default_release_info_version_code }}_${{ needs.build-release.outputs.default_release_info_version_name }}_default_x86.apk \ - --group Public-x86 \ - --token ${{ secrets.APP_CENTER_TOKEN }} \ - --release-notes "${{ needs.build-release.outputs.changelog }}" + # upload to github release - - name: Upload default release apk to app center (x86_64) - id: upload-default-release-apk-x86_64 - uses: nick-fields/retry@v2 + - name: Publish Release + uses: softprops/action-gh-release@v2 with: - timeout_minutes: 1 - max_attempts: 5 - command: | - appcenter distribute release \ - --app aaa1115910-gmail.com/BV \ - --file BV_${{ needs.build-release.outputs.default_release_info_version_code }}_${{ needs.build-release.outputs.default_release_info_version_name }}_default_x86_64.apk \ - --group Public-x86_64 \ - --token ${{ secrets.APP_CENTER_TOKEN }} \ - --release-notes "${{ needs.build-release.outputs.changelog }}" + files: | + app/build/outputs/apk/default/debug/BV_${{ env.release_debug_info_version_code }}_${{ env.release_debug_info_version_name }}_default_universal.apk + app/build/outputs/apk/default/release/BV_${{ env.release_info_version_code }}_${{ env.release_info_version_name }}_default_universal.apk + app/build/outputs/mapping/defaultAlpha + tag_name: ${{ github.ref_name }} + name: ${{ env.release_info_version_name }} + prerelease: false + body: ${{ env.changelog }} + target_commitish: ${{ github.sha }} diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1c67a368..2a2b9808 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -124,7 +124,7 @@ android { } } - splits { + /*splits { if (gradle.startParameter.taskNames.find { it.startsWith("assembleDefault") } != null) { abi { isEnable = true @@ -133,7 +133,7 @@ android { isUniversalApk = true } } - } + }*/ applicationVariants.configureEach { val variant = this From f6548bb8917f5491c720c7601f05dcad764812fb Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Mon, 29 Apr 2024 23:08:34 +0800 Subject: [PATCH 11/19] =?UTF-8?q?=E5=B0=86=E6=9B=B4=E6=96=B0=E6=B8=A0?= =?UTF-8?q?=E9=81=93=E4=BB=8E=20MS=20AppCenter=20=E6=9B=B4=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=20Github=20Release?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bv/component/settings/UpdateDialog.kt | 48 +-- .../dev/aaa1115910/bv/network/AppCenterApi.kt | 408 ------------------ .../dev/aaa1115910/bv/network/GithubApi.kt | 129 ++++++ .../dev/aaa1115910/bv/network/VlcLibsApi.kt | 12 +- .../entity/{Releases.kt => GithubRelease.kt} | 72 ++-- .../screen/settings/content/AboutSetting.kt | 11 +- app/src/test/kotlin/android/util/Log.kt | 16 + .../aaa1115910/bv/network/AppCenterApiTest.kt | 57 --- .../aaa1115910/bv/network/GithubApiTest.kt | 16 + 9 files changed, 222 insertions(+), 547 deletions(-) delete mode 100644 app/src/main/kotlin/dev/aaa1115910/bv/network/AppCenterApi.kt create mode 100644 app/src/main/kotlin/dev/aaa1115910/bv/network/GithubApi.kt rename app/src/main/kotlin/dev/aaa1115910/bv/network/entity/{Releases.kt => GithubRelease.kt} (62%) create mode 100644 app/src/test/kotlin/android/util/Log.kt delete mode 100644 app/src/test/kotlin/dev/aaa1115910/bv/network/AppCenterApiTest.kt create mode 100644 app/src/test/kotlin/dev/aaa1115910/bv/network/GithubApiTest.kt diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/component/settings/UpdateDialog.kt b/app/src/main/kotlin/dev/aaa1115910/bv/component/settings/UpdateDialog.kt index d2459185..d6d99d45 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/component/settings/UpdateDialog.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/component/settings/UpdateDialog.kt @@ -14,7 +14,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf -import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -30,8 +29,11 @@ import androidx.tv.material3.ExperimentalTvMaterial3Api import androidx.tv.material3.OutlinedButton import androidx.tv.material3.Text import dev.aaa1115910.bv.BuildConfig -import dev.aaa1115910.bv.network.AppCenterApi -import dev.aaa1115910.bv.network.PackageInfo +import dev.aaa1115910.bv.network.GithubApi +import dev.aaa1115910.bv.network.entity.Release +import dev.aaa1115910.bv.util.fException +import dev.aaa1115910.bv.util.fInfo +import io.github.oshai.kotlinlogging.KotlinLogging import io.ktor.client.content.ProgressListener import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -47,6 +49,7 @@ fun UpdateDialog( ) { val context = LocalContext.current val scope = rememberCoroutineScope() + val logger = KotlinLogging.logger("UpdateDialog") var updateStatus by remember { mutableStateOf(UpdateStatus.UpdatingInfo) } @@ -58,40 +61,31 @@ fun UpdateDialog( label = "update progress" ) - var latestPackageId by remember { mutableIntStateOf(0) } - var packageInfo: PackageInfo? by remember { mutableStateOf(null) } + var latestReleaseBuild by remember { mutableStateOf(null) } val checkUpdate: () -> Unit = { updateStatus = UpdateStatus.UpdatingInfo scope.launch(Dispatchers.IO) { runCatching { - val availablePackageList = AppCenterApi.getPackageList() - val latestPackage = availablePackageList.first() - if (latestPackage.version.toInt() <= BuildConfig.VERSION_CODE) { + latestReleaseBuild = GithubApi.getLatestBuild() + val revision = latestReleaseBuild!! + .assets.first { it.name.startsWith("BV") } + .name.split("_")[1].toInt() + if (revision < BuildConfig.VERSION_CODE) { updateStatus = UpdateStatus.NoAvailableUpdate return@launch - } else { - latestPackageId = latestPackage.id } - - packageInfo = AppCenterApi.getPackageInfo(latestPackageId) }.onFailure { + logger.fException(it) { "Failed to get latest version" } updateStatus = UpdateStatus.CheckError }.onSuccess { + logger.fInfo { "Find latest version ${latestReleaseBuild!!.name}" } updateStatus = UpdateStatus.Ready } } } - val sendInstallAnalytics: () -> Unit = { - scope.launch(Dispatchers.IO) { - runCatching { - AppCenterApi.sendInstallAnalytics(latestPackageId) - } - } - } - val installUpdate: (File) -> Unit = { file -> updateStatus = UpdateStatus.Installing runCatching { @@ -118,8 +112,8 @@ fun UpdateDialog( val tempFile = File(tempDir, tempFilename) tempFile.createNewFile() runCatching { - AppCenterApi.downloadFile( - packageInfo!!.downloadUrl, + GithubApi.downloadUpdate( + latestReleaseBuild!!, tempFile, object : ProgressListener { override suspend fun invoke(downloaded: Long, total: Long) { @@ -130,9 +124,9 @@ fun UpdateDialog( .getOrDefault(0f) } }) - if (!BuildConfig.DEBUG) sendInstallAnalytics() if (show) installUpdate(tempFile) }.onFailure { + logger.fException(it) { "Failed to download update" } updateStatus = UpdateStatus.DownloadError } } @@ -160,7 +154,7 @@ fun UpdateDialog( Text( text = when (updateStatus) { UpdateStatus.UpdatingInfo -> "获取更新信息中" - UpdateStatus.Ready -> packageInfo!!.shortVersion + UpdateStatus.Ready -> latestReleaseBuild!!.name UpdateStatus.Downloading -> "下载中" UpdateStatus.Installing -> "安装中" UpdateStatus.NoAvailableUpdate -> "无可用更新" @@ -177,7 +171,7 @@ fun UpdateDialog( } UpdateStatus.Ready -> { - Text(text = packageInfo?.releaseNotes ?: "") + Text(text = latestReleaseBuild?.body ?: "Empty content") } UpdateStatus.Downloading -> { @@ -185,8 +179,8 @@ fun UpdateDialog( verticalArrangement = Arrangement.spacedBy(8.dp) ) { LinearProgressIndicator( - progress = progress, - modifier = Modifier.fillMaxWidth() + progress = { progress }, + modifier = Modifier.fillMaxWidth(), ) Row( modifier = Modifier.fillMaxWidth(), diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/network/AppCenterApi.kt b/app/src/main/kotlin/dev/aaa1115910/bv/network/AppCenterApi.kt deleted file mode 100644 index 85ae8268..00000000 --- a/app/src/main/kotlin/dev/aaa1115910/bv/network/AppCenterApi.kt +++ /dev/null @@ -1,408 +0,0 @@ -package dev.aaa1115910.bv.network - -import dev.aaa1115910.bv.BuildConfig -import dev.aaa1115910.bv.util.AbiUtil -import dev.aaa1115910.bv.util.Prefs -import io.github.oshai.kotlinlogging.KotlinLogging -import io.ktor.client.HttpClient -import io.ktor.client.call.body -import io.ktor.client.content.ProgressListener -import io.ktor.client.engine.okhttp.OkHttp -import io.ktor.client.plugins.BrowserUserAgent -import io.ktor.client.plugins.compression.ContentEncoding -import io.ktor.client.plugins.contentnegotiation.ContentNegotiation -import io.ktor.client.plugins.defaultRequest -import io.ktor.client.plugins.onDownload -import io.ktor.client.request.get -import io.ktor.client.request.parameter -import io.ktor.client.request.post -import io.ktor.client.request.prepareRequest -import io.ktor.client.request.setBody -import io.ktor.client.request.url -import io.ktor.client.statement.bodyAsChannel -import io.ktor.http.ContentType -import io.ktor.http.URLProtocol -import io.ktor.http.contentType -import io.ktor.serialization.kotlinx.json.json -import io.ktor.util.cio.writeChannel -import io.ktor.utils.io.copyAndClose -import kotlinx.serialization.KSerializer -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonElement -import java.io.File -import java.text.SimpleDateFormat -import java.util.Date -import java.util.Locale -import java.util.TimeZone -import java.util.UUID - -private const val OWNER_NAME = "aaa1115910-gmail.com" -private const val APP_NAME = "bv" - -object AppCenterApi { - private var endPoint = "install.appcenter.ms" - private lateinit var client: HttpClient - private val logger = KotlinLogging.logger { } - - init { - createClient() - } - - private fun createClient() { - client = HttpClient(OkHttp) { - BrowserUserAgent() - install(ContentNegotiation) { - json(Json { - coerceInputValues = true - ignoreUnknownKeys = true - prettyPrint = true - }) - } - install(ContentEncoding) { - deflate(1.0F) - gzip(0.9F) - } - defaultRequest { - url { - protocol = URLProtocol.HTTPS - host = endPoint - } - } - } - } - - suspend fun getPackageList( - ownerName: String, - appName: String, - distributionGroupName: String, - scope: String? = null, - top: Int? = null - ): List = - client.get("/api/v0.1/apps/$ownerName/$appName/distribution_groups/$distributionGroupName/public_releases") { - scope?.let { parameter("scope", it) } - top?.let { parameter("top", it) } - }.body() - - suspend fun getPackageInfo( - ownerName: String, - appName: String, - distributionGroupName: String, - releaseId: Int, - isInstallPage: Boolean? = null - ): PackageInfo = - client.get("/api/v0.1/apps/$ownerName/$appName/distribution_groups/$distributionGroupName/releases/$releaseId") { - isInstallPage?.let { parameter("is_install_page", it) } - }.body() - - suspend fun sendInstallAnalytics( - ownerName: String, - appName: String, - distributionGroupId: String, - releaseId: Int, - userId: String = UUID.randomUUID().toString() - ) { - val result = client.post("/api/v0.1/public/apps/$ownerName/$appName/install_analytics") { - contentType(ContentType.Application.Json) - setBody(InstallAnalytics.create(releaseId, distributionGroupId, userId)) - } - require("${result.status}".startsWith("2")) { "Send install analytics failed" } - } - - suspend fun downloadFile( - downloadUrl: String, - //fileOutputStream: FileOutputStream, - file: File, - downloadListener: ProgressListener - ) { - //client.get(downloadUrl).bodyAsChannel().toInputStream().copyTo(fileOutputStream) - client.prepareRequest { - url(downloadUrl) - onDownload(downloadListener) - }.execute { response -> - response.bodyAsChannel().copyAndClose(file.writeChannel()) - } - } - - private fun getGroupName() = GroupData(BuildConfig.FLAVOR, getAbiType()).getGroupName() - private fun getGroupId() = GroupData(BuildConfig.FLAVOR, getAbiType()).getGroupId() - - private fun getAbiType(): String { - val abiSet = AbiUtil.getApkSupportedAbiSet() - - return when { - abiSet.size > 1 || abiSet.isEmpty() -> "universal" - else -> abiSet.first() - } - } - - suspend fun getPackageList() = getPackageList( - ownerName = OWNER_NAME, - appName = APP_NAME, - distributionGroupName = getGroupName() - ) - - suspend fun getPackageInfo(releaseId: Int) = getPackageInfo( - ownerName = OWNER_NAME, - appName = APP_NAME, - distributionGroupName = getGroupName(), - releaseId = releaseId, - ) - - suspend fun sendInstallAnalytics(releaseId: Int) { - sendInstallAnalytics( - ownerName = OWNER_NAME, - appName = APP_NAME, - distributionGroupId = getGroupId(), - releaseId = releaseId - ) - } - - suspend fun getLatestVersion(): Pair { - val list = getPackageList(OWNER_NAME, APP_NAME, getGroupName()) - return Pair(list.first().version.toInt(), list.first().shortVersion) - } -} - -/** - * 已发布的版本 - * - * @param id - * @param shortVersion 版本名称 - * @param version 版本号 - * @param origin 来源 - * @param uploadedAt 发布时间 - * @param mandatoryUpdate - * @param enabled - * @param isExternalBuild - */ -@Serializable -data class ReleasePackage( - val id: Int, - @SerialName("short_version") - val shortVersion: String, - val version: String, - val origin: String, - @SerialName("uploaded_at") - @Serializable(with = DateSerializer::class) - val uploadedAt: Date? = null, - @SerialName("mandatory_update") - val mandatoryUpdate: Boolean, - val enabled: Boolean, - @SerialName("is_external_build") - val isExternalBuild: Boolean -) - -/** - * 安装包信息 - * - * @param appName 应用名称 - * @param appDisplayName 应用显示名称 - * @param appOs 应用支持的系统 - * @param owner 开发者 - * @param isExternalBuild - * @param origin 来源 - * @param id - * @param version 版本号 - * @param shortVersion 版本名称 - * @param size 应用大小 - * @param minOs 支持的最低系统版本 - * @param androidMinApiLevel 支持的最低 Android API 版本 - * @param deviceFamily - * @param bundleIdentifier 应用包名 - * @param fingerprint MD5 - * @param uploadedAt 发布时间 - * @param downloadUrl 下载链接 - * @param installUrl 安装链接 - * @param mandatoryUpdate - * @param enabled - * @param fileExtension 文件类型 - * @param isLatest 是否为最新版 - * @param releaseNotes 更新日志 - * @param isUdidProvisioned - * @param canResign - * @param packageHashes - * @param destinationType - * @param status - * @param distributionGroupId - * @param distributionGroups - */ -@Serializable -data class PackageInfo( - @SerialName("app_name") - val appName: String, - @SerialName("app_display_name") - val appDisplayName: String, - @SerialName("app_os") - val appOs: String, - val owner: Owner, - @SerialName("is_external_build") - val isExternalBuild: Boolean, - val origin: String, - val id: Int, - val version: String, - @SerialName("short_version") - val shortVersion: String, - val size: Long, - @SerialName("min_os") - val minOs: String, - @SerialName("android_min_api_level") - val androidMinApiLevel: String, - @SerialName("device_family") - val deviceFamily: JsonElement? = null, - @SerialName("bundle_identifier") - val bundleIdentifier: String, - val fingerprint: String, - @SerialName("uploaded_at") - @Serializable(with = DateSerializer::class) - val uploadedAt: Date? = null, - @SerialName("download_url") - val downloadUrl: String, - @SerialName("install_url") - val installUrl: String, - @SerialName("mandatory_update") - val mandatoryUpdate: Boolean, - val enabled: Boolean, - val fileExtension: String, - @SerialName("is_latest") - val isLatest: Boolean, - @SerialName("release_notes") - val releaseNotes: String, - @SerialName("is_udid_provisioned") - val isUdidProvisioned: JsonElement? = null, - @SerialName("can_resign") - val canResign: JsonElement? = null, - @SerialName("package_hashes") - val packageHashes: List = emptyList(), - @SerialName("destination_type") - val destinationType: String, - val status: String, - @SerialName("distribution_group_id") - val distributionGroupId: String, - @SerialName("distribution_groups") - val distributionGroups: List = emptyList() -) { - /** - * 开发者 - * - * @param name 用户名称 - * @param display_name 用户显示名称 - */ - @Serializable - data class Owner( - val name: String, - @SerialName("display_name") - val display_name: String - ) - - /** - * 分发用户组 - * - * @param id - * @param name 用户组名称 - * @param origin 来源 - * @param displayName 用户组显示名称 - * @param isPublic 是否公开用户组 - */ - @Serializable - data class DistributionGroups( - val id: String, - val name: String, - val origin: String, - @SerialName("display_name") - val displayName: String, - @SerialName("is_public") - val isPublic: Boolean - ) -} - -@Serializable -data class InstallAnalytics( - val releases: List = emptyList() -) { - companion object { - fun create( - releaseId: Int, - distributionGroupId: String, - userId: String - ): InstallAnalytics { - return InstallAnalytics( - releases = listOf(InstallAnalyticsItem(releaseId, distributionGroupId, userId)) - ) - } - } - - /** - * @param releaseId id - * @param distributionGroupId 分发用户组id [UUID] - * @param userId 用户id [UUID] - */ - @Serializable - data class InstallAnalyticsItem( - @SerialName("release_id") - val releaseId: Int, - @SerialName("distribution_group_id") - val distributionGroupId: String, - @SerialName("user_id") - val userId: String - ) -} - -object DateSerializer : KSerializer { - @Suppress("SpellCheckingInspection") - private val sdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US).apply { - timeZone = TimeZone.getTimeZone("GMT") - } - override val descriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.STRING) - - override fun deserialize(decoder: Decoder): Date? { - return sdf.parse(decoder.decodeString()) - } - - override fun serialize(encoder: Encoder, value: Date?) { - encoder.encodeString(sdf.format(value ?: Date(0))) - } -} - -private data class GroupData( - val flavor: String, - val abiType: String -) { - fun getGroupName(): String { - val prefix = if (Prefs.updateAlpha) "Alpha" else "Public" - return if (flavor == "lite") prefix else "$prefix-$abiType" - } - - fun getGroupId(): String { - return if (Prefs.updateAlpha) { - if (flavor == "lite") { - "d867ff94-66f2-4338-8aa2-ce86e2acd649" - } else { - when (abiType) { - "armeabi-v7a" -> "8796ecb5-a6f0-4194-a7d9-73ada5be7f66" - "arm64-v8a" -> "136d3a56-e052-449b-b493-a8ba5c024711" - "x86" -> "e62422ae-1439-462e-ac41-cd83fe17fa14" - "x86_64" -> "147899f9-8d07-4414-96de-0dd52cfed7e7" - else -> "9954160d-6a3d-4ea3-965c-7245832dfb8d" - } - } - } else { - if (flavor == "lite") { - "9259f371-d475-4088-b9fe-e5adfac1b563" - } else { - when (abiType) { - "armeabi-v7a" -> "8cc6402a-4129-4009-84d2-16a1fe2ef039" - "arm64-v8a" -> "b4fc8b5b-735c-4e71-aa70-cd3b36b68adc" - "x86" -> "c63e16ca-88d1-48fb-bf2b-6b614b14bc09" - "x86_64" -> "e9a1ae2f-3158-4074-9c97-59627f8d67ec" - else -> "a450d9a9-44c9-40d3-94e4-ab2e1f1cb26f" - } - } - } - } -} \ No newline at end of file diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/network/GithubApi.kt b/app/src/main/kotlin/dev/aaa1115910/bv/network/GithubApi.kt new file mode 100644 index 00000000..278be1de --- /dev/null +++ b/app/src/main/kotlin/dev/aaa1115910/bv/network/GithubApi.kt @@ -0,0 +1,129 @@ +package dev.aaa1115910.bv.network + +import dev.aaa1115910.bv.BuildConfig +import dev.aaa1115910.bv.network.entity.Release +import dev.aaa1115910.bv.util.Prefs +import io.ktor.client.HttpClient +import io.ktor.client.content.ProgressListener +import io.ktor.client.engine.okhttp.OkHttp +import io.ktor.client.plugins.BrowserUserAgent +import io.ktor.client.plugins.compression.ContentEncoding +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.plugins.defaultRequest +import io.ktor.client.plugins.onDownload +import io.ktor.client.request.get +import io.ktor.client.request.parameter +import io.ktor.client.request.prepareRequest +import io.ktor.client.request.url +import io.ktor.client.statement.bodyAsChannel +import io.ktor.client.statement.bodyAsText +import io.ktor.http.URLProtocol +import io.ktor.serialization.kotlinx.json.json +import io.ktor.util.cio.writeChannel +import io.ktor.utils.io.copyAndClose +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import java.io.File + +object GithubApi { + private var endPoint = "api.github.com" + private const val OWNER = "aaa1115910" + private const val REPO = "bv" + private lateinit var client: HttpClient + private val json = Json { + coerceInputValues = true + ignoreUnknownKeys = true + prettyPrint = true + } + private val isDebug get() = BuildConfig.DEBUG + private val isAlpha get() = Prefs.updateAlpha + + init { + createClient() + } + + private fun createClient() { + client = HttpClient(OkHttp) { + BrowserUserAgent() + install(ContentNegotiation) { + json(json) + } + install(ContentEncoding) { + deflate(1.0F) + gzip(0.9F) + } + defaultRequest { + url { + protocol = URLProtocol.HTTPS + host = endPoint + } + } + } + } + + private suspend fun getReleases( + owner: String = OWNER, + repo: String = REPO, + pageSize: Int = 30, + page: Int = 1 + ): List { + val response = client.get("repos/$owner/$repo/releases") { + parameter("per_page", pageSize) + parameter("page", page) + }.bodyAsText() + checkErrorMessage(response) + return json.decodeFromString>(response) + } + + 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) + } + + suspend fun getLatestPreReleaseBuild(): Release { + var release: Release? = null + var page = 1 + while (release == null) { + val releases = getReleases(page = page) + if (releases.isEmpty()) break + release = releases.firstOrNull { it.isPreRelease } + page++ + } + return release ?: throw IllegalStateException("No pre-release found") + } + + suspend fun getLatestReleaseBuild(): Release = getLatestRelease() + + suspend fun getLatestBuild(): Release = + if (isAlpha) getLatestPreReleaseBuild() else getLatestReleaseBuild() + + private fun checkErrorMessage(data: String) { + val responseElement = json.parseToJsonElement(data) + if (responseElement !is JsonObject) return + val responseObject = responseElement.jsonObject + check(responseObject.size != 2 && responseObject["message"] == null) { responseObject["message"]!!.jsonPrimitive.content } + } + + suspend fun downloadUpdate( + release: Release, + file: File, + downloadListener: ProgressListener + ) { + val downloadUrl = + if (isDebug) release.assets.firstOrNull { it.name.contains("debug") }?.browserDownloadUrl + else release.assets.firstOrNull { it.name.contains("alpha") || it.name.contains("release") }?.browserDownloadUrl + downloadUrl ?: throw IllegalStateException("Didn't find download url") + client.prepareRequest { + url(downloadUrl) + onDownload(downloadListener) + }.execute { response -> + response.bodyAsChannel().copyAndClose(file.writeChannel()) + } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/network/VlcLibsApi.kt b/app/src/main/kotlin/dev/aaa1115910/bv/network/VlcLibsApi.kt index c791ca51..5f283198 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/network/VlcLibsApi.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/network/VlcLibsApi.kt @@ -1,7 +1,7 @@ package dev.aaa1115910.bv.network import android.os.Build -import dev.aaa1115910.bv.network.entity.ReleaseItem +import dev.aaa1115910.bv.network.entity.Release import io.ktor.client.HttpClient import io.ktor.client.call.body import io.ktor.client.content.ProgressListener @@ -53,24 +53,24 @@ object VlcLibsApi { } } - suspend fun getReleases(): List { - val result = mutableListOf() + suspend fun getReleases(): List { + val result = mutableListOf() runCatching { result.addAll( - client.get("/repos/aaa1115910/bv-libs/releases").body>() + client.get("/repos/aaa1115910/bv-libs/releases").body>() ) } return result } - suspend fun getRelease(vlcVersion: String): ReleaseItem? { + suspend fun getRelease(vlcVersion: String): Release? { return getReleases().firstOrNull { it.tagName == "libvlc-${vlcVersion}" } } suspend fun downloadFile( - releaseItem: ReleaseItem, + releaseItem: Release, file: File, downloadListener: ProgressListener ) { diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/network/entity/Releases.kt b/app/src/main/kotlin/dev/aaa1115910/bv/network/entity/GithubRelease.kt similarity index 62% rename from app/src/main/kotlin/dev/aaa1115910/bv/network/entity/Releases.kt rename to app/src/main/kotlin/dev/aaa1115910/bv/network/entity/GithubRelease.kt index f336dfb3..0b510672 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/network/entity/Releases.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/network/entity/GithubRelease.kt @@ -2,14 +2,13 @@ package dev.aaa1115910.bv.network.entity import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.json.JsonElement @Serializable -data class ReleaseItem( +data class Release( val assets: List, @SerialName("assets_url") val assetsUrl: String, - val author: Author, + val author: User, val body: String, @SerialName("created_at") val createdAt: String, @@ -20,10 +19,10 @@ data class ReleaseItem( val name: String, @SerialName("node_id") val nodeId: String, - @SerialName("prerelease") - val preRelease: Boolean, + val prerelease: Boolean, @SerialName("published_at") val publishedAt: String, + val reactions: Reactions, @SerialName("tag_name") val tagName: String, @SerialName("tarball_url") @@ -36,6 +35,9 @@ data class ReleaseItem( @SerialName("zipball_url") val zipballUrl: String ) { + val isPreRelease = prerelease + val isRelease = !prerelease + @Serializable data class Asset( @SerialName("browser_download_url") @@ -47,7 +49,7 @@ data class ReleaseItem( @SerialName("download_count") val downloadCount: Int, val id: Int, - val label: JsonElement? = null, + val label: String, val name: String, @SerialName("node_id") val nodeId: String, @@ -55,48 +57,12 @@ data class ReleaseItem( val state: String, @SerialName("updated_at") val updatedAt: String, - val uploader: Uploader, + val uploader: User, val url: String - ) { - @Serializable - data class Uploader( - @SerialName("avatar_url") - val avatarUrl: String, - @SerialName("events_url") - val eventsUrl: String, - @SerialName("followers_url") - val followersUrl: String, - @SerialName("following_url") - val followingUrl: String, - @SerialName("gists_url") - val gistsUrl: String, - @SerialName("gravatar_id") - val gravatarId: String, - @SerialName("html_url") - val htmlUrl: String, - val id: Int, - val login: String, - @SerialName("node_id") - val nodeId: String, - @SerialName("organizations_url") - val organizationsUrl: String, - @SerialName("received_events_url") - val receivedEventsUrl: String, - @SerialName("repos_url") - val reposUrl: String, - @SerialName("site_admin") - val siteAdmin: Boolean, - @SerialName("starred_url") - val starredUrl: String, - @SerialName("subscriptions_url") - val subscriptionsUrl: String, - val type: String, - val url: String - ) - } + ) @Serializable - data class Author( + data class User( @SerialName("avatar_url") val avatarUrl: String, @SerialName("events_url") @@ -130,4 +96,18 @@ data class ReleaseItem( val type: String, val url: String ) -} \ No newline at end of file + + @Serializable + data class Reactions( + @SerialName("+1") + val like: Int, + @SerialName("-1") + val dislike: Int, + val laugh: Int, + val hooray: Int, + val confused: Int, + val heart: Int, + val rocket: Int, + val eyes: Int + ) +} diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/content/AboutSetting.kt b/app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/content/AboutSetting.kt index 9a5eaf3f..2b2da8f7 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/content/AboutSetting.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/content/AboutSetting.kt @@ -26,9 +26,12 @@ import androidx.tv.material3.Text import dev.aaa1115910.bv.BuildConfig import dev.aaa1115910.bv.R import dev.aaa1115910.bv.component.settings.UpdateDialog -import dev.aaa1115910.bv.network.AppCenterApi +import dev.aaa1115910.bv.network.GithubApi import dev.aaa1115910.bv.screen.settings.SettingsMenuNavItem import dev.aaa1115910.bv.ui.theme.BVTheme +import dev.aaa1115910.bv.util.fException +import dev.aaa1115910.bv.util.fInfo +import io.github.oshai.kotlinlogging.KotlinLogging import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -38,6 +41,7 @@ fun AboutSetting( modifier: Modifier = Modifier ) { val context = LocalContext.current + val logger = KotlinLogging.logger("AboutSetting") var showUpdateDialog by remember { mutableStateOf(false) } var latestVersionName by remember { mutableStateOf("Loading...") } @@ -45,9 +49,10 @@ fun AboutSetting( LaunchedEffect(Unit) { launch(Dispatchers.IO) { runCatching { - val latestVersion = AppCenterApi.getLatestVersion() - latestVersionName = latestVersion.second + latestVersionName = GithubApi.getLatestBuild().name + logger.fInfo { "Find latest version $latestVersionName" } }.onFailure { + logger.fException(it) { "Failed to get latest version" } latestVersionName = "Error" } } diff --git a/app/src/test/kotlin/android/util/Log.kt b/app/src/test/kotlin/android/util/Log.kt new file mode 100644 index 00000000..d4ee3990 --- /dev/null +++ b/app/src/test/kotlin/android/util/Log.kt @@ -0,0 +1,16 @@ +package android.util + +class Log { + companion object { + @JvmStatic + fun isLoggable(tag: String, level: Int): Boolean { + return true + } + + @JvmStatic + fun println(priority: Int, tag: String, msg: String): Int { + println("[$tag] $msg") + return 0 + } + } +} \ No newline at end of file diff --git a/app/src/test/kotlin/dev/aaa1115910/bv/network/AppCenterApiTest.kt b/app/src/test/kotlin/dev/aaa1115910/bv/network/AppCenterApiTest.kt deleted file mode 100644 index 87deca47..00000000 --- a/app/src/test/kotlin/dev/aaa1115910/bv/network/AppCenterApiTest.kt +++ /dev/null @@ -1,57 +0,0 @@ -package dev.aaa1115910.bv.network - -import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.Assertions.assertDoesNotThrow -import kotlin.test.Test - -internal class AppCenterApiTest { - - companion object { - private const val ownerName = "aaa1115910-gmail.com" - private const val appName = "bv" - private const val distributionGroupName = "public" - private const val distributionGroupId = "9259f371-d475-4088-b9fe-e5adfac1b563" - private const val releaseId = 18 - } - - @Test - fun `check update available packages`() { - runBlocking { - println( - AppCenterApi.getPackageList( - ownerName = ownerName, - appName = appName, - distributionGroupName = distributionGroupName - ) - ) - } - } - - @Test - fun `get update package info`() { - runBlocking { - println( - AppCenterApi.getPackageInfo( - ownerName = ownerName, - appName = appName, - distributionGroupName = distributionGroupName, - releaseId = releaseId - ) - ) - } - } - - @Test - fun `send install analytics`() { - assertDoesNotThrow { - runBlocking { - AppCenterApi.sendInstallAnalytics( - ownerName = ownerName, - appName = appName, - distributionGroupId = distributionGroupId, - releaseId = releaseId - ) - } - } - } -} \ No newline at end of file diff --git a/app/src/test/kotlin/dev/aaa1115910/bv/network/GithubApiTest.kt b/app/src/test/kotlin/dev/aaa1115910/bv/network/GithubApiTest.kt new file mode 100644 index 00000000..5ba22b55 --- /dev/null +++ b/app/src/test/kotlin/dev/aaa1115910/bv/network/GithubApiTest.kt @@ -0,0 +1,16 @@ +package dev.aaa1115910.bv.network + +import kotlinx.coroutines.runBlocking +import kotlin.test.Test + +class GithubApiTest { + @Test + fun `get latest release build`() = runBlocking { + println(GithubApi.getLatestReleaseBuild()) + } + + @Test + fun `get latest pre-release build`() = runBlocking { + println(GithubApi.getLatestPreReleaseBuild()) + } +} \ No newline at end of file From c70189560fbc0b21ad5bb458631f55d14e1a3a1d Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Mon, 29 Apr 2024 23:37:24 +0800 Subject: [PATCH 12/19] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9C=AA=E8=83=BD?= =?UTF-8?q?=E5=B0=86=20mapping=20=E4=B8=8A=E4=BC=A0=E8=87=B3=20github=20re?= =?UTF-8?q?lease?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/alpha.yml | 7 ++++++- .github/workflows/release.yml | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/alpha.yml b/.github/workflows/alpha.yml index 9801c646..d2d3dd99 100644 --- a/.github/workflows/alpha.yml +++ b/.github/workflows/alpha.yml @@ -103,6 +103,11 @@ jobs: name: Alpha build artifact path: app/build/outputs/apk/default/alpha/BV_${{ env.alpha_info_version_code }}_${{ env.alpha_info_version_name }}_default_universal.apk + # zip mapping because softprops/action-gh-release can't upload folder + + - name: Zip mapping + run: zip -rj mapping.zip app/build/outputs/mapping/defaultAlpha + # upload to github release - name: Publish Pre-Release @@ -111,7 +116,7 @@ jobs: files: | app/build/outputs/apk/default/debug/BV_${{ env.alpha_debug_info_version_code }}_${{ env.alpha_debug_info_version_name }}_default_universal.apk app/build/outputs/apk/default/alpha/BV_${{ env.alpha_info_version_code }}_${{ env.alpha_info_version_name }}_default_universal.apk - app/build/outputs/mapping/defaultAlpha + mapping.zip tag_name: ${{ env.tag_name }} name: ${{ env.alpha_info_version_name }} prerelease: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9d359ec5..7e54e764 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -100,6 +100,11 @@ jobs: name: Release build artifact path: app/build/outputs/apk/default/release/BV_${{ env.release_info_version_code }}_${{ env.release_info_version_name }}_default_universal.apk + # zip mapping because softprops/action-gh-release can't upload folder + + - name: Zip mapping + run: zip -rj mapping.zip app/build/outputs/mapping/defaultRelease + # upload to github release - name: Publish Release @@ -108,7 +113,7 @@ jobs: files: | app/build/outputs/apk/default/debug/BV_${{ env.release_debug_info_version_code }}_${{ env.release_debug_info_version_name }}_default_universal.apk app/build/outputs/apk/default/release/BV_${{ env.release_info_version_code }}_${{ env.release_info_version_name }}_default_universal.apk - app/build/outputs/mapping/defaultAlpha + mapping.zip tag_name: ${{ github.ref_name }} name: ${{ env.release_info_version_name }} prerelease: false From d1daa2032e3a0bf216e9d631ba6a28bb68ded530 Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Mon, 29 Apr 2024 23:44:24 +0800 Subject: [PATCH 13/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20actions=20=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Node.js 16 actions 已被弃用 --- .github/workflows/alpha.yml | 10 +++--- .../alpha_build_manually_without_sign.yml | 32 +++++++++---------- .github/workflows/features.yml | 10 +++--- .github/workflows/release.yml | 10 +++--- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/.github/workflows/alpha.yml b/.github/workflows/alpha.yml index d2d3dd99..92bf3d91 100644 --- a/.github/workflows/alpha.yml +++ b/.github/workflows/alpha.yml @@ -13,14 +13,14 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: develop fetch-depth: 0 submodules: 'true' - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' @@ -84,7 +84,7 @@ jobs: # upload artifacts alpha debug - name: Archive alpha debug build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Alpha debug build artifact path: app/build/outputs/apk/default/debug/BV_${{ env.alpha_debug_info_version_code }}_${{ env.alpha_debug_info_version_name }}_default_universal.apk @@ -92,13 +92,13 @@ jobs: # upload artifacts alpha - name: Archive default alpha build mappings - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Alpha build mappings path: app/build/outputs/mapping/defaultAlpha - name: Archive alpha build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Alpha build artifact path: app/build/outputs/apk/default/alpha/BV_${{ env.alpha_info_version_code }}_${{ env.alpha_info_version_name }}_default_universal.apk diff --git a/.github/workflows/alpha_build_manually_without_sign.yml b/.github/workflows/alpha_build_manually_without_sign.yml index 4a580910..08b96dc3 100644 --- a/.github/workflows/alpha_build_manually_without_sign.yml +++ b/.github/workflows/alpha_build_manually_without_sign.yml @@ -14,14 +14,14 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: develop fetch-depth: 0 submodules: 'true' - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' @@ -81,7 +81,7 @@ jobs: # upload artifacts lite-debug - name: Archive lite debug build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Lite debug build artifact path: app/build/outputs/apk/lite/debug/${{ env.lite_debug_info_apk_filename }} @@ -89,13 +89,13 @@ jobs: # upload artifacts lite-alpha - name: Archive lite alpha build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Lite alpha build artifact path: app/build/outputs/apk/lite/alpha/${{ env.lite_alpha_info_apk_filename }} - name: Archive lite alpha build mappings - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Lite alpha build mappings path: app/build/outputs/mapping/liteAlpha @@ -103,31 +103,31 @@ jobs: # upload artifacts default-debug - name: Archive default debug build artifacts (universal) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Default debug build artifact (universal) path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_universal.apk - name: Archive default debug build artifacts (armeabi-v7a) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Default debug build artifact (armeabi-v7a) path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_armeabi-v7a.apk - name: Archive default debug build artifacts (arm64-v8a) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Default debug build artifact (arm64-v8a) path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_arm64-v8a.apk - name: Archive default debug build artifacts (x86) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Default debug build artifact (x86) path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_x86.apk - name: Archive default debug build artifacts (x86_64) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Default debug build artifact (x86_64) path: app/build/outputs/apk/default/debug/BV_${{ env.default_debug_info_version_code }}_${{ env.default_debug_info_version_name }}_default_x86_64.apk @@ -135,37 +135,37 @@ jobs: # upload artifacts default-alpha - name: Archive default alpha build mappings - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Default alpha build mappings path: app/build/outputs/mapping/defaultAlpha - name: Archive default alpha build artifacts (universal) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Default alpha build artifact (universal) path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_universal.apk - name: Archive default alpha build artifacts (armeabi-v7a) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Default alpha build artifact (armeabi-v7a) path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_armeabi-v7a.apk - name: Archive default alpha build artifacts (arm64-v8a) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Default alpha build artifact (arm64-v8a) path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_arm64-v8a.apk - name: Archive default alpha build artifacts (x86) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Default alpha build artifact (x86) path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_x86.apk - name: Archive default alpha build artifacts (x86_64) - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Default alpha build artifact (x86_64) path: app/build/outputs/apk/default/alpha/BV_${{ env.default_alpha_info_version_code }}_${{ env.default_alpha_info_version_name }}_default_x86_64.apk diff --git a/.github/workflows/features.yml b/.github/workflows/features.yml index 6e258a7e..e52d7064 100644 --- a/.github/workflows/features.yml +++ b/.github/workflows/features.yml @@ -13,14 +13,14 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ github.ref }} fetch-depth: 0 submodules: 'true' - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' @@ -71,7 +71,7 @@ jobs: # upload artifacts alpha debug - name: Archive alpha debug build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Alpha debug build artifact path: app/build/outputs/apk/default/debug/BV_${{ env.alpha_debug_info_version_code }}_${{ env.alpha_debug_info_version_name }}_default_universal.apk @@ -79,13 +79,13 @@ jobs: # upload artifacts alpha - name: Archive alpha build mappings - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Alpha build mappings path: app/build/outputs/mapping/defaultAlpha - name: Archive alpha build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Alpha build artifact path: app/build/outputs/apk/default/alpha/BV_${{ env.alpha_info_version_code }}_${{ env.alpha_info_version_name }}_default_universal.apk diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7e54e764..34f84bb3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,14 +14,14 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: master fetch-depth: 0 submodules: 'true' - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' @@ -81,7 +81,7 @@ jobs: # upload artifacts release debug - name: Archive release debug build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Release debug build artifact path: app/build/outputs/apk/default/debug/BV_${{ env.release_debug_info_version_code }}_${{ env.release_debug_info_version_name }}_default_universal.apk @@ -89,13 +89,13 @@ jobs: # upload artifacts release - name: Archive release build mappings - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Release build mappings path: app/build/outputs/mapping/defaultRelease - name: Archive release build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Release build artifact path: app/build/outputs/apk/default/release/BV_${{ env.release_info_version_code }}_${{ env.release_info_version_name }}_default_universal.apk From dedeaaf32a891708f91224c4b4a9be2ef3434ac6 Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Tue, 30 Apr 2024 00:36:37 +0800 Subject: [PATCH 14/19] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=E5=8F=AF=E8=83=BD=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/dev/aaa1115910/bv/network/entity/GithubRelease.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/network/entity/GithubRelease.kt b/app/src/main/kotlin/dev/aaa1115910/bv/network/entity/GithubRelease.kt index 0b510672..3f0dbe2a 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/network/entity/GithubRelease.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/network/entity/GithubRelease.kt @@ -22,7 +22,7 @@ data class Release( val prerelease: Boolean, @SerialName("published_at") val publishedAt: String, - val reactions: Reactions, + val reactions: Reactions? = null, @SerialName("tag_name") val tagName: String, @SerialName("tarball_url") From d7e490fe3094902458300957b0d154c26d4784b1 Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Sun, 12 May 2024 18:17:04 +0800 Subject: [PATCH 15/19] =?UTF-8?q?=E5=9C=A8=E7=95=AA=E5=89=A7=E9=A1=B5?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=89=93=E5=BC=80=E5=8B=95=E7=95=AB=E9=A2=A8?= =?UTF-8?q?=E7=9A=84=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 麻麻再也不用担心我看番切换应用时得返回桌面了 --- app/src/main/AndroidManifest.xml | 4 + .../aaa1115910/bv/screen/home/AnimeScreen.kt | 87 ++++++++++++++++--- app/src/main/res/drawable/ic_gamer_ani.xml | 32 +++++++ app/src/main/res/values/strings.xml | 3 +- 4 files changed, 113 insertions(+), 13 deletions(-) create mode 100644 app/src/main/res/drawable/ic_gamer_ani.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 632bab84..dcfb6d49 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,6 +17,10 @@ android:name="android.hardware.wifi" android:required="false" /> + + + + Unit, onOpenFollowing: () -> Unit, onOpenIndex: () -> Unit, - onOpenUnknown: () -> Unit = {} + onOpenGamerAni: () -> Unit = {} ) { val buttons = listOf( Triple( @@ -237,9 +249,9 @@ private fun AnimeFeatureButtons( onOpenIndex ), Triple( - stringResource(R.string.anime_home_button_unknown), - Icons.Rounded.QuestionMark, - onOpenUnknown + stringResource(R.string.anime_home_button_gamer_ani), + painterResource(R.drawable.ic_gamer_ani), + onOpenGamerAni ) ) @@ -248,12 +260,23 @@ private fun AnimeFeatureButtons( horizontalArrangement = Arrangement.spacedBy(24.dp) ) { buttons.forEach { (title, icon, onClick) -> - AnimeFeatureButton( - modifier = Modifier.weight(1f), - title = title, - icon = icon, - onClick = onClick - ) + when (icon) { + is ImageVector -> AnimeFeatureButton( + modifier = Modifier.weight(1f), + title = title, + icon = icon, + onClick = onClick + ) + + is Painter -> AnimeFeatureButton( + modifier = Modifier.weight(1f), + title = title, + icon = icon, + onClick = onClick + ) + + else -> {} + } } } } @@ -294,6 +317,46 @@ fun AnimeFeatureButton( } } +@OptIn(ExperimentalTvMaterial3Api::class) +@Composable +fun AnimeFeatureButton( + modifier: Modifier = Modifier, + title: String, + icon: Painter, + onClick: () -> Unit +) { + Surface( + modifier = modifier, + colors = ClickableSurfaceDefaults.colors( + containerColor = MaterialTheme.colorScheme.surfaceVariant, + focusedContainerColor = MaterialTheme.colorScheme.inverseSurface, + pressedContainerColor = MaterialTheme.colorScheme.inverseSurface + ), + shape = ClickableSurfaceDefaults.shape(shape = MaterialTheme.shapes.large), + onClick = onClick + ) { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + Icon( + modifier = Modifier.size(24.dp), + painter = icon, + contentDescription = null + ) + Text( + text = title, + style = MaterialTheme.typography.titleLarge + ) + } + } + } +} + @Composable fun AnimeFeedVideoRow( modifier: Modifier = Modifier, @@ -470,7 +533,7 @@ fun AnimeFeatureButtonsPreview() { onOpenTimeline = {}, onOpenFollowing = {}, onOpenIndex = {}, - onOpenUnknown = {} + onOpenGamerAni = {} ) } } diff --git a/app/src/main/res/drawable/ic_gamer_ani.xml b/app/src/main/res/drawable/ic_gamer_ani.xml new file mode 100644 index 00000000..d4a49878 --- /dev/null +++ b/app/src/main/res/drawable/ic_gamer_ani.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b5202865..0d6aaeda 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,9 +1,9 @@ 正在追 + 動畫風 索引 时间表 - 待定 BV @@ -333,4 +333,5 @@ https://www.bilibili.com Bilibili Freedoooooom/MarkII Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 + 未安装動畫風 From 75321a379893996d4403cdcad0ce03ec0e738d26 Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Mon, 13 May 2024 22:23:23 +0800 Subject: [PATCH 16/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新 badge - 更新下载地址 --- .github/ISSUE_TEMPLATE/bug_report.yml | 4 ++-- README.md | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 2b7373c3..9e29bf1a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -52,8 +52,8 @@ body: attributes: label: 请确认已更新到以下所示的最新版本 description: | - ![App Center Release](https://img.shields.io/endpoint?url=https%3A%2F%2Fbadge.versions.bv.aaa1115910.dev%2F%3Ftype%3Drelease) - ![App Center Alpha](https://img.shields.io/endpoint?url=https%3A%2F%2Fbadge.versions.bv.aaa1115910.dev%2F%3Ftype%3Dalpha) + ![GitHub Release Release](https://img.shields.io/github/v/release/aaa1115910/bv?display_name=release&label=release) + ![GitHub Release Pre-Release](https://img.shields.io/github/v/release/aaa1115910/bv?include_prereleases&display_name=release&label=alpha) options: - '我正在使用旧版本' - '已更新到最新 Release 版' diff --git a/README.md b/README.md index 21b93ff0..5464f2ab 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,12 @@ ~~Bug Video~~ -[![App Center Release](https://img.shields.io/endpoint?url=https%3A%2F%2Fbadge.versions.bv.aaa1115910.dev%2F%3Ftype%3Drelease)](https://install.appcenter.ms/users/aaa1115910-gmail.com/apps/bv/distribution_groups/public) -[![App Center Alpha](https://img.shields.io/endpoint?url=https%3A%2F%2Fbadge.versions.bv.aaa1115910.dev%2F%3Ftype%3Dalpha)](https://install.appcenter.ms/users/aaa1115910-gmail.com/apps/bv/distribution_groups/alpha) +[![GitHub Release Release](https://img.shields.io/github/v/release/aaa1115910/bv?display_name=release&label=release)](https://github.com/aaa1115910/bv/releases?q=prerelease%3Afalse) +[![GitHub Release Pre-Release](https://img.shields.io/github/v/release/aaa1115910/bv?include_prereleases&display_name=release&label=alpha)](https://github.com/aaa1115910/bv/releases?q=prerelease%3Atrue) [![Workflow Release](https://github.com/aaa1115910/bv/actions/workflows/release.yml/badge.svg)](https://github.com/aaa1115910/bv/actions/workflows/release.yml) [![Workflow Alpha](https://github.com/aaa1115910/bv/actions/workflows/alpha.yml/badge.svg)](https://github.com/aaa1115910/bv/actions/workflows/alpha.yml) -[![Android Sdk Require](https://img.shields.io/badge/android-5.0%2B-informational)](https://developer.android.com/jetpack/compose/interop/adding#:~:text=minimum%20API%20level%20to%2021%20or%20higher%2C) +[![Android Sdk Require](https://img.shields.io/badge/Android-5.0%2B-informational?logo=android)](https://apilevels.com/#:~:text=Jetpack%20Compose%20requires%20a%20minSdk%20of%2021%20or%20higher) [![GitHub](https://img.shields.io/github/license/aaa1115910/bv)](https://github.com/aaa1115910/bv) **BV 不支持在中国大陆地区内使用,如有相关使用需求请使用 [云视听小电视](https://app.bilibili.com)** @@ -36,13 +36,11 @@ BV ~~(Bug Video)~~ 是一款 [哔哩哔哩](https://www.bilibili.com) 的第三 ### Release -- [Github Actions](https://github.com/aaa1115910/bv/actions/workflows/release.yml) -- [AppCenter](https://install.appcenter.ms/users/aaa1115910-gmail.com/apps/bv/distribution_groups/public) +- [Github Release](https://github.com/aaa1115910/bv/releases?q=prerelease%3Afalse) ### Alpha -- [Github Actions](https://github.com/aaa1115910/bv/actions/workflows/alpha.yml) -- [AppCenter](https://install.appcenter.ms/users/aaa1115910-gmail.com/apps/bv/distribution_groups/alpha) +- [Github Release](https://github.com/aaa1115910/bv/releases?q=prerelease%3Atrue) ## License From 8511f436c4df6bf35053644c3de62ed919eac845 Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Tue, 14 May 2024 19:19:09 +0800 Subject: [PATCH 17/19] =?UTF-8?q?=E6=9B=B4=E6=94=B9=20aid=20cid=20?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=B1=BB=E5=9E=8B=20`int`=20->=20`long`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RemoteControllerPanelDemoActivity.kt | 8 ++-- .../bv/activities/video/VideoInfoActivity.kt | 2 +- .../activities/video/VideoPlayerActivity.kt | 8 ++-- .../activities/video/VideoPlayerV3Activity.kt | 8 ++-- .../controllers/VideoPlayerController.kt | 4 +- .../controllers2/VideoListController.kt | 2 +- .../bv/entity/carddata/VideoCardData.kt | 2 +- .../bv/repository/VideoInfoRepository.kt | 4 +- .../aaa1115910/bv/screen/SeasonInfoScreen.kt | 24 ++++++------ .../aaa1115910/bv/screen/VideoInfoScreen.kt | 21 +++++----- .../bv/screen/user/UserInfoScreen.kt | 2 +- .../aaa1115910/bv/util/PlayerActivityUtil.kt | 4 +- .../bv/viewmodel/PlayerVIewModel.kt | 18 ++++----- .../bv/viewmodel/VideoPlayerV3ViewModel.kt | 14 +++---- .../bv/viewmodel/user/FavoriteViewModel.kt | 2 +- .../viewmodel/video/VideoDetailViewModel.kt | 4 +- .../bilibili/playershared/playershared.proto | 4 +- .../biliapi/entity/home/RecommendItem.kt | 2 +- .../aaa1115910/biliapi/entity/rank/Popular.kt | 4 +- .../aaa1115910/biliapi/entity/user/Dynamic.kt | 14 +++---- .../aaa1115910/biliapi/entity/user/History.kt | 8 ++-- .../aaa1115910/biliapi/entity/user/Space.kt | 8 ++-- .../biliapi/entity/video/RelatedVideo.kt | 4 +- .../biliapi/entity/video/VideoDetail.kt | 12 +++--- .../biliapi/entity/video/VideoPage.kt | 4 +- .../biliapi/entity/video/season/Episode.kt | 10 ++--- .../aaa1115910/biliapi/http/BiliHttpApi.kt | 38 +++++++++---------- .../biliapi/http/BiliHttpProxyApi.kt | 4 +- .../biliapi/http/BiliPassportHttpApi.kt | 4 +- .../biliapi/http/BiliPlusHttpApi.kt | 4 +- .../biliapi/http/entity/biliplus/View.kt | 16 ++++---- .../http/entity/history/HistoryData.kt | 4 +- .../biliapi/http/entity/home/RcmdIndexData.kt | 6 +-- .../biliapi/http/entity/home/RcmdTopData.kt | 4 +- .../biliapi/http/entity/proxy/PlayUrl.kt | 4 +- .../http/entity/search/SearchResultItem.kt | 2 +- .../biliapi/http/entity/season/Episode.kt | 2 +- .../http/entity/user/SpaceVideoData.kt | 6 +-- .../http/entity/video/PlayUrlResponse.kt | 2 +- .../entity/video/RelatedVideosResponse.kt | 4 +- .../biliapi/http/entity/video/UgcSeason.kt | 6 +-- .../biliapi/http/entity/video/VideoInfo.kt | 10 ++--- .../http/entity/video/VideoMoreInfo.kt | 8 ++-- .../repositories/FavoriteRepository.kt | 10 ++--- .../biliapi/repositories/SearchRepository.kt | 4 +- .../repositories/VideoDetailRepository.kt | 2 +- .../repositories/VideoPlayRepository.kt | 16 ++++---- .../repositories/VideoPlayRepositoryTest.kt | 2 +- 48 files changed, 178 insertions(+), 177 deletions(-) diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/RemoteControllerPanelDemoActivity.kt b/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/RemoteControllerPanelDemoActivity.kt index 755c23d4..afe745b9 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/RemoteControllerPanelDemoActivity.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/RemoteControllerPanelDemoActivity.kt @@ -19,8 +19,8 @@ class RemoteControllerPanelDemoActivity : ComponentActivity() { companion object { fun actionStart( context: Context, - avid: Int, - cid: Int, + avid: Long, + cid: Long, title: String, partTitle: String, played: Int, @@ -70,8 +70,8 @@ fun RemoteControllerPanelDemoScreen( Prefs.showedRemoteControllerPanelDemo = true VideoPlayerV3Activity.actionStart( context = context, - avid = intent.getIntExtra("avid", 0), - cid = intent.getIntExtra("cid", 0), + avid = intent.getLongExtra("avid", 0), + cid = intent.getLongExtra("cid", 0), title = intent.getStringExtra("title") ?: "", partTitle = intent.getStringExtra("partTitle") ?: "", played = intent.getIntExtra("played", 0), diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoInfoActivity.kt b/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoInfoActivity.kt index 7ede224e..facc1427 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoInfoActivity.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoInfoActivity.kt @@ -12,7 +12,7 @@ import dev.aaa1115910.bv.ui.theme.BVTheme class VideoInfoActivity : ComponentActivity() { companion object { fun actionStart( - context: Context, aid: Int, + context: Context, aid: Long, fromSeason: Boolean = false, proxyArea: ProxyArea = ProxyArea.MainLand ) { diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoPlayerActivity.kt b/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoPlayerActivity.kt index eb11efb1..a2660d56 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoPlayerActivity.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoPlayerActivity.kt @@ -28,8 +28,8 @@ class VideoPlayerActivity : ComponentActivity() { private val logger = KotlinLogging.logger { } fun actionStart( context: Context, - avid: Int, - cid: Int, + avid: Long, + cid: Long, title: String, partTitle: String, played: Int, @@ -70,8 +70,8 @@ class VideoPlayerActivity : ComponentActivity() { playerViewModel.preparePlayer(player) if (intent.hasExtra("avid")) { - val aid = intent.getIntExtra("avid", 170001) - val cid = intent.getIntExtra("cid", 170001) + val aid = intent.getLongExtra("avid", 170001) + val cid = intent.getLongExtra("cid", 170001) val title = intent.getStringExtra("title") ?: "Unknown Title" val partTitle = intent.getStringExtra("partTitle") ?: "Unknown Part Title" val played = intent.getIntExtra("played", 0) diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoPlayerV3Activity.kt b/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoPlayerV3Activity.kt index ca79e59d..75774c48 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoPlayerV3Activity.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoPlayerV3Activity.kt @@ -25,8 +25,8 @@ class VideoPlayerV3Activity : ComponentActivity() { private val logger = KotlinLogging.logger { } fun actionStart( context: Context, - avid: Int, - cid: Int, + avid: Long, + cid: Long, title: String, partTitle: String, played: Int, @@ -106,8 +106,8 @@ class VideoPlayerV3Activity : ComponentActivity() { private fun getParamsFromIntent() { if (intent.hasExtra("avid")) { - val aid = intent.getIntExtra("avid", 170001) - val cid = intent.getIntExtra("cid", 170001) + val aid = intent.getLongExtra("avid", 170001) + val cid = intent.getLongExtra("cid", 170001) val title = intent.getStringExtra("title") ?: "Unknown Title" val partTitle = intent.getStringExtra("partTitle") ?: "Unknown Part Title" val played = intent.getIntExtra("played", 0) diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/component/controllers/VideoPlayerController.kt b/app/src/main/kotlin/dev/aaa1115910/bv/component/controllers/VideoPlayerController.kt index 53a81dfc..f2d7c429 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/component/controllers/VideoPlayerController.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/component/controllers/VideoPlayerController.kt @@ -65,7 +65,7 @@ fun VideoPlayerController( availableVideoCodec: List = emptyList(), availableSubtitle: List = emptyList(), availableVideoList: List = emptyList(), - currentVideoCid: Int = 0, + currentVideoCid: Long = 0, currentResolution: Int? = null, currentVideoCodec: VideoCodec = VideoCodec.AVC, currentVideoAspectRatio: VideoAspectRatio = VideoAspectRatio.Default, @@ -472,7 +472,7 @@ data class VideoPlayerControllerData( val availableSubtitle: List = emptyList(), val availableSubtitleTracks: List = emptyList(), val availableVideoList: List = emptyList(), - val currentVideoCid: Int = 0, + val currentVideoCid: Long = 0, val currentResolution: Int? = null, val currentVideoCodec: VideoCodec = VideoCodec.AVC, val currentVideoAspectRatio: VideoAspectRatio = VideoAspectRatio.Default, diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/component/controllers2/VideoListController.kt b/app/src/main/kotlin/dev/aaa1115910/bv/component/controllers2/VideoListController.kt index 7c141551..2e1288b2 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/component/controllers2/VideoListController.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/component/controllers2/VideoListController.kt @@ -36,7 +36,7 @@ import dev.aaa1115910.bv.util.requestFocus fun VideoListController( modifier: Modifier = Modifier, show: Boolean, - currentCid: Int, + currentCid: Long, videoList: List, onPlayNewVideo: (VideoListItem) -> Unit ) { diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/entity/carddata/VideoCardData.kt b/app/src/main/kotlin/dev/aaa1115910/bv/entity/carddata/VideoCardData.kt index abe9b4c0..e6132d18 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/entity/carddata/VideoCardData.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/entity/carddata/VideoCardData.kt @@ -3,7 +3,7 @@ package dev.aaa1115910.bv.entity.carddata import dev.aaa1115910.bv.util.formatMinSec data class VideoCardData( - val avid: Int, + val avid: Long, val title: String, val cover: String, val upName: String, diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/repository/VideoInfoRepository.kt b/app/src/main/kotlin/dev/aaa1115910/bv/repository/VideoInfoRepository.kt index 8ba2c71a..b2b845ad 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/repository/VideoInfoRepository.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/repository/VideoInfoRepository.kt @@ -5,8 +5,8 @@ class VideoInfoRepository { } data class VideoListItem( - val aid: Int, - val cid: Int, + val aid: Long, + val cid: Long, val epid: Int? = null, val seasonId: Int? = null, val title: String, diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/screen/SeasonInfoScreen.kt b/app/src/main/kotlin/dev/aaa1115910/bv/screen/SeasonInfoScreen.kt index 693269ce..84985760 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/screen/SeasonInfoScreen.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/screen/SeasonInfoScreen.kt @@ -149,10 +149,10 @@ fun SeasonInfoScreen( val defaultFocusRequester = remember { FocusRequester() } - val onClickVideo: (avid: Int, cid: Int, epid: Int, episodeTitle: String, startTime: Int) -> Unit = + val onClickVideo: (avid: Long, cid: Long, epid: Int, episodeTitle: String, startTime: Int) -> Unit = { avid, cid, epid, episodeTitle, startTime -> logger.debug { "onClickVideo: [avid=$avid, cid=$cid, epid=$epid, episodeTitle=$episodeTitle, startTime=$startTime]" } - if (cid != 0) { + if (cid != 0L) { launchPlayerActivity( context = context, avid = avid, @@ -290,8 +290,8 @@ fun SeasonInfoScreen( seasonCount = seasonData!!.seasons.size, onPlay = { logger.fInfo { "Click play button" } - var playAid = -1 - var playCid = -1 + var playAid = -1L + var playCid = -1L val playEpid: Int var episodeList: List = emptyList() if (lastPlayProgress == null) { @@ -300,7 +300,7 @@ fun SeasonInfoScreen( playAid = seasonData?.episodes?.first()?.aid ?: -1 playCid = seasonData?.episodes?.first()?.cid ?: -1 playEpid = seasonData?.episodes?.first()?.id ?: -1 - if (playCid == -1) { + if (playCid == -1L) { R.string.season_no_feature_film.toast(context) } else { episodeList = seasonData?.episodes ?: emptyList() @@ -318,7 +318,7 @@ fun SeasonInfoScreen( episodeList = seasonData?.episodes ?: emptyList() } } - if (playCid == -1) { + if (playCid == -1L) { seasonData?.sections?.forEach { section -> section.episodes.forEach { if (it.id == playEpid) { @@ -329,7 +329,7 @@ fun SeasonInfoScreen( } } } - if (playCid == -1) { + if (playCid == -1L) { logger.fInfo { "Can't find cid" } "无法判断最后播放的剧集".toast(context) } @@ -337,7 +337,7 @@ fun SeasonInfoScreen( logger.fInfo { "Play aid: $playAid, cid: $playCid" } - if (playCid != -1) { + if (playCid != -1L) { onClickVideo( playAid, playCid, @@ -733,7 +733,7 @@ fun SeasonEpisodesDialog( lastPlayedId: Int = 0, lastPlayedTime: Int = 0, onHideDialog: () -> Unit, - onClick: (avid: Int, cid: Int, epid: Int, episodeTitle: String, startTime: Int) -> Unit + onClick: (avid: Long, cid: Long, epid: Int, episodeTitle: String, startTime: Int) -> Unit ) { val scope = rememberCoroutineScope() @@ -840,7 +840,7 @@ fun SeasonEpisodesDialog( duration = episode.duration, onClick = { onClick( - episode.aid.toInt(), + episode.aid, episode.cid, episode.id, episode.longTitle, @@ -864,7 +864,7 @@ fun SeasonEpisodeRow( episodes: List, lastPlayedId: Int = 0, lastPlayedTime: Int = 0, - onClick: (avid: Int, cid: Int, epid: Int, episodeTitle: String, startTime: Int) -> Unit + onClick: (avid: Long, cid: Long, epid: Int, episodeTitle: String, startTime: Int) -> Unit ) { val focusRestorerModifiers = createCustomInitialFocusRestorerModifiers() var hasFocus by remember { mutableStateOf(false) } @@ -940,7 +940,7 @@ fun SeasonEpisodeRow( duration = episode.duration, onClick = { onClick( - episode.aid.toInt(), + episode.aid, episode.cid, episode.id, episode.longTitle, diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/screen/VideoInfoScreen.kt b/app/src/main/kotlin/dev/aaa1115910/bv/screen/VideoInfoScreen.kt index ab9cd577..bad521e3 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/screen/VideoInfoScreen.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/screen/VideoInfoScreen.kt @@ -35,6 +35,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -150,7 +151,7 @@ fun VideoInfoScreen( var showFollowButton by remember { mutableStateOf(false) } var isFollowing by remember { mutableStateOf(false) } - var lastPlayedCid by remember { mutableIntStateOf(0) } + var lastPlayedCid by remember { mutableLongStateOf(0) } var lastPlayedTime by remember { mutableIntStateOf(0) } var tip by remember { mutableStateOf("Loading") } @@ -225,7 +226,7 @@ fun VideoInfoScreen( } } - val fetchFavoriteData: (Int) -> Unit = { avid -> + val fetchFavoriteData: (Long) -> Unit = { avid -> scope.launch(Dispatchers.IO) { runCatching { val favoriteFolderMetadataListResult = @@ -303,7 +304,7 @@ fun VideoInfoScreen( LaunchedEffect(Unit) { if (intent.hasExtra("aid")) { - val aid = intent.getIntExtra("aid", 170001) + val aid = intent.getLongExtra("aid", 170001) fromSeason = intent.getBooleanExtra("fromSeason", false) proxyArea = ProxyArea.entries[intent.getIntExtra("proxyArea", 0)] //获取视频信息 @@ -1069,10 +1070,10 @@ private fun VideoPartRowButton( fun VideoPartRow( modifier: Modifier = Modifier, pages: List, - lastPlayedCid: Int = 0, + lastPlayedCid: Long = 0, lastPlayedTime: Int = 0, enablePartListDialog: Boolean = false, - onClick: (cid: Int) -> Unit + onClick: (cid: Long) -> Unit ) { val focusRestorerModifiers = createCustomInitialFocusRestorerModifiers() var hasFocus by remember { mutableStateOf(false) } @@ -1138,10 +1139,10 @@ fun VideoUgcSeasonRow( modifier: Modifier = Modifier, title: String, episodes: List, - lastPlayedCid: Int = 0, + lastPlayedCid: Long = 0, lastPlayedTime: Int = 0, enableUgcListDialog: Boolean = false, - onClick: (avid: Int, cid: Int) -> Unit + onClick: (avid: Long, cid: Long) -> Unit ) { val focusRestorerModifiers = createCustomInitialFocusRestorerModifiers() var hasFocus by remember { mutableStateOf(false) } @@ -1209,7 +1210,7 @@ private fun VideoPartListDialog( title: String, pages: List, onHideDialog: () -> Unit, - onClick: (cid: Int) -> Unit + onClick: (cid: Long) -> Unit ) { val scope = rememberCoroutineScope() @@ -1318,7 +1319,7 @@ private fun VideoUgcListDialog( title: String, episodes: List, onHideDialog: () -> Unit, - onClick: (avid: Int, cid: Int) -> Unit + onClick: (avid: Long, cid: Long) -> Unit ) { val scope = rememberCoroutineScope() @@ -1453,7 +1454,7 @@ fun VideoPartRowPreview() { for (i in 0..10) { pages.add( VideoPage( - cid = 1000 + i, + cid = 1000L + i, index = i, title = "这可能是我这辈子距离梅西最近的一次", duration = 10, diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/screen/user/UserInfoScreen.kt b/app/src/main/kotlin/dev/aaa1115910/bv/screen/user/UserInfoScreen.kt index eca2d0f8..f6957f9e 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/screen/user/UserInfoScreen.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/screen/user/UserInfoScreen.kt @@ -235,7 +235,7 @@ fun UserInfoScreen( favoriteItems.forEach { favoriteItem -> favorites.add( VideoCardData( - avid = favoriteItem.id.toInt(), + avid = favoriteItem.id, title = favoriteItem.title, cover = favoriteItem.cover, upName = favoriteItem.upper.name, diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/util/PlayerActivityUtil.kt b/app/src/main/kotlin/dev/aaa1115910/bv/util/PlayerActivityUtil.kt index a7c73f36..86cece16 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/util/PlayerActivityUtil.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/util/PlayerActivityUtil.kt @@ -8,8 +8,8 @@ import dev.aaa1115910.bv.entity.proxy.ProxyArea fun launchPlayerActivity( context: Context, - avid: Int, - cid: Int, + avid: Long, + cid: Long, title: String, partTitle: String, played: Int, diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/PlayerVIewModel.kt b/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/PlayerVIewModel.kt index 675776f4..a4c3bfc0 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/PlayerVIewModel.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/PlayerVIewModel.kt @@ -93,8 +93,8 @@ class PlayerViewModel( var showLogs by mutableStateOf(false) var showBuffering by mutableStateOf(false) - private var currentAid = 0 - var currentCid = 0 + private var currentAid = 0L + var currentCid = 0L companion object { private val logger = KotlinLogging.logger { } @@ -119,8 +119,8 @@ class PlayerViewModel( } fun loadPlayUrl( - avid: Int, - cid: Int, + avid: Long, + cid: Long, epid: Int? = null, seasonId: Int? = null ) { @@ -147,8 +147,8 @@ class PlayerViewModel( } private suspend fun loadPlayUrl( - avid: Int, - cid: Int, + avid: Long, + cid: Long, fnval: Int = 4048, qn: Int = 80, fnver: Int = 0, @@ -295,7 +295,7 @@ class PlayerViewModel( } } - suspend fun loadDanmaku(cid: Int) { + suspend fun loadDanmaku(cid: Long) { runCatching { val danmakuXmlData = BiliHttpApi.getDanmakuXml(cid = cid, sessData = Prefs.sessData) @@ -358,7 +358,7 @@ class PlayerViewModel( if (!fromSeason) { logger.info { "Send heartbeat: [avid=$currentAid, cid=$currentCid, time=$time]" } BiliHttpApi.sendHeartbeat( - avid = currentAid.toLong(), + avid = currentAid, cid = currentCid, playedTime = time, csrf = Prefs.biliJct, @@ -367,7 +367,7 @@ class PlayerViewModel( } else { logger.info { "Send heartbeat: [avid=$currentAid, cid=$currentCid, epid=$epid, sid=$seasonId, time=$time]" } BiliHttpApi.sendHeartbeat( - avid = currentAid.toLong(), + avid = currentAid, cid = currentCid, playedTime = time, type = 4, diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/VideoPlayerV3ViewModel.kt b/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/VideoPlayerV3ViewModel.kt index 36fca4f9..cfc4017f 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/VideoPlayerV3ViewModel.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/VideoPlayerV3ViewModel.kt @@ -108,8 +108,8 @@ class VideoPlayerV3ViewModel( var lastChangedLog by mutableLongStateOf(System.currentTimeMillis()) var showBuffering by mutableStateOf(false) - private var currentAid = 0 - var currentCid = 0 + private var currentAid = 0L + var currentCid = 0L private var currentEpid = 0 private suspend fun releaseDanmakuPlayer() = withContext(Dispatchers.Main) { @@ -121,8 +121,8 @@ class VideoPlayerV3ViewModel( } fun loadPlayUrl( - avid: Int, - cid: Int, + avid: Long, + cid: Long, epid: Int? = null, seasonId: Int? = null, continuePlayNext: Boolean = false @@ -161,8 +161,8 @@ class VideoPlayerV3ViewModel( } private suspend fun loadPlayUrl( - avid: Int, - cid: Int, + avid: Long, + cid: Long, epid: Int = 0, preferApi: ApiType = Prefs.apiType, proxyArea: ProxyArea = ProxyArea.MainLand @@ -355,7 +355,7 @@ class VideoPlayerV3ViewModel( } } - suspend fun loadDanmaku(cid: Int) { + suspend fun loadDanmaku(cid: Long) { runCatching { val danmakuXmlData = BiliHttpApi.getDanmakuXml(cid = cid, sessData = Prefs.sessData) diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/user/FavoriteViewModel.kt b/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/user/FavoriteViewModel.kt index 105240c7..026cea19 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/user/FavoriteViewModel.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/user/FavoriteViewModel.kt @@ -83,7 +83,7 @@ class FavoriteViewModel( if (favoriteItem.type != FavoriteItemType.Video) return@forEach favorites.add( VideoCardData( - avid = favoriteItem.id.toInt(), + avid = favoriteItem.id, title = favoriteItem.title, cover = favoriteItem.cover, upName = favoriteItem.upper.name, diff --git a/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/video/VideoDetailViewModel.kt b/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/video/VideoDetailViewModel.kt index ccf2652b..6fbbc2dc 100644 --- a/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/video/VideoDetailViewModel.kt +++ b/app/src/main/kotlin/dev/aaa1115910/bv/viewmodel/video/VideoDetailViewModel.kt @@ -22,7 +22,7 @@ class VideoDetailViewModel( var relatedVideos = mutableStateListOf() - suspend fun loadDetail(aid: Int) { + suspend fun loadDetail(aid: Long) { logger.fInfo { "Load detail: [avid=$aid, preferApiType=${Prefs.apiType.name}]" } state = VideoInfoState.Loading runCatching { @@ -41,7 +41,7 @@ class VideoDetailViewModel( }.getOrThrow() } - suspend fun loadDetailOnlyUpdateHistory(aid: Int) { + suspend fun loadDetailOnlyUpdateHistory(aid: Long) { logger.fInfo { "Load detail only update history: [avid=$aid, preferApiType=${Prefs.apiType.name}]" } runCatching { videoDetail?.history = videoDetailRepository.getVideoDetail( diff --git a/bili-api-grpc/proto/bilibili/playershared/playershared.proto b/bili-api-grpc/proto/bilibili/playershared/playershared.proto index f6156720..d20c7e78 100644 --- a/bili-api-grpc/proto/bilibili/playershared/playershared.proto +++ b/bili-api-grpc/proto/bilibili/playershared/playershared.proto @@ -760,9 +760,9 @@ enum UnsupportScene { // 播放页信息-请求: 音视频VOD message VideoVod { // 视频aid - int32 aid = 1; + int64 aid = 1; // 视频cid - int32 cid = 2; + int64 cid = 2; // 清晰度 uint64 qn = 3; // 视频流版本 diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/home/RecommendItem.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/home/RecommendItem.kt index 805df00e..b1e59ed5 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/home/RecommendItem.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/home/RecommendItem.kt @@ -3,7 +3,7 @@ package dev.aaa1115910.biliapi.entity.home import dev.aaa1115910.biliapi.util.convertStringTimeToSeconds data class RecommendItem( - val aid: Int, + val aid: Long, val bvid: String, val title: String, val cover: String, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/rank/Popular.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/rank/Popular.kt index ec731ef8..c61d79cc 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/rank/Popular.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/rank/Popular.kt @@ -13,7 +13,7 @@ data class PopularVideoPage( ) data class PopularVideo( - val aid: Int, + val aid: Long, val title: String, val duration: Int, val author: String, @@ -37,7 +37,7 @@ data class PopularVideo( fun fromSmallCoverV5(card: bilibili.app.card.v1.SmallCoverV5) = PopularVideo( - aid = card.base.param.toInt(), + aid = card.base.param.toLong(), title = card.base.title, duration = convertStringTimeToSeconds(card.coverRightText1), author = card.rightDesc1, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/user/Dynamic.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/user/Dynamic.kt index acef9497..3a9bf088 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/user/Dynamic.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/user/Dynamic.kt @@ -51,9 +51,9 @@ data class DynamicVideoData( * @property danmaku 视频弹幕数 */ data class DynamicVideo( - val aid: Int, + val aid: Long, val bvid: String? = null, - val cid: Int, + val cid: Long, val epid: Int? = null, val seasonId: Int? = null, val title: String, @@ -68,7 +68,7 @@ data class DynamicVideo( val archive = item.modules.moduleDynamic.major!!.archive!! val author = item.modules.moduleAuthor return DynamicVideo( - aid = archive.aid.toInt(), + aid = archive.aid.toLong(), bvid = archive.bvid, cid = 0, title = archive.title @@ -93,9 +93,9 @@ data class DynamicVideo( ModuleDynamic.ModuleItemCase.DYN_ARCHIVE -> { val archive = dynamic.dynArchive return DynamicVideo( - aid = archive.avid.toInt(), + aid = archive.avid, bvid = archive.bvid, - cid = archive.cid.toInt(), + cid = archive.cid, title = if (!isDynamicVideo) archive.title else desc!!.text.substring(5), cover = archive.cover, author = author.name, @@ -108,9 +108,9 @@ data class DynamicVideo( ModuleDynamic.ModuleItemCase.DYN_PGC -> { val pgc = dynamic.dynPgc return DynamicVideo( - aid = pgc.aid.toInt(), + aid = pgc.aid, bvid = null, - cid = pgc.cid.toInt(), + cid = pgc.cid, epid = pgc.cid.toInt(), seasonId = pgc.seasonId.toInt(), title = pgc.title, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/user/History.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/user/History.kt index a514de84..e3acede6 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/user/History.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/user/History.kt @@ -26,9 +26,9 @@ data class HistoryData( } data class HistoryItem( - val oid: Int, + val oid: Long, val bvid: String, - val cid: Int, + val cid: Long, val kid: Int, val epid: Int?, val seasonId: Int?, @@ -62,14 +62,14 @@ data class HistoryItem( @Suppress("RemoveRedundantQualifierName") fun fromHistoryItem(item: bilibili.app.interfaces.v1.CursorItem) = HistoryItem( - oid = item.oid.toInt(), + oid = item.oid, bvid = when (item.cardItemCase) { CursorItem.CardItemCase.CARD_UGC -> item.cardUgc.bvid CursorItem.CardItemCase.CARD_OGV -> "" else -> "" }, cid = when (item.cardItemCase) { - CursorItem.CardItemCase.CARD_UGC -> item.cardUgc.cid.toInt() + CursorItem.CardItemCase.CARD_UGC -> item.cardUgc.cid CursorItem.CardItemCase.CARD_OGV -> 0 else -> 0 }, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/user/Space.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/user/Space.kt index 5ea39d4d..ebf600cd 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/user/Space.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/user/Space.kt @@ -25,14 +25,14 @@ data class SpaceVideoData( .map { SpaceVideo.fromSpaceVideoItem(it) }, page = SpaceVideoPage( hasNext = appSpaceVideoData.hasNext, - lastAvid = appSpaceVideoData.item.lastOrNull()?.param?.toInt() ?: 0 + lastAvid = appSpaceVideoData.item.lastOrNull()?.param?.toLong() ?: 0 ) ) } } data class SpaceVideo( - val aid: Int, + val aid: Long, val bvid: String, val title: String, val cover: String, @@ -56,7 +56,7 @@ data class SpaceVideo( fun fromSpaceVideoItem(spaceVideoItem: dev.aaa1115910.biliapi.http.entity.user.AppSpaceVideoData.SpaceVideoItem) = SpaceVideo( - aid = spaceVideoItem.param.toInt(), + aid = spaceVideoItem.param.toLong(), bvid = spaceVideoItem.bvid, title = spaceVideoItem.title, cover = spaceVideoItem.cover, @@ -85,5 +85,5 @@ data class SpaceVideoPage( val nextWebPageSize: Int = 20, val nextWebPageNumber: Int = 1, // app - val lastAvid: Int = 0 + val lastAvid: Long = 0 ) \ No newline at end of file diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/RelatedVideo.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/RelatedVideo.kt index 3e678e98..7ef2e0f7 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/RelatedVideo.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/RelatedVideo.kt @@ -4,7 +4,7 @@ import bilibili.app.view.v1.authorOrNull import dev.aaa1115910.biliapi.entity.user.Author data class RelatedVideo( - val aid: Int, + val aid: Long, val cover: String, val title: String, val duration: Int, @@ -16,7 +16,7 @@ data class RelatedVideo( ) { companion object { fun fromRelate(relate: bilibili.app.view.v1.Relate) = RelatedVideo( - aid = relate.aid.toInt(), + aid = relate.aid, cover = relate.pic, title = relate.title, duration = relate.duration.toInt(), diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/VideoDetail.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/VideoDetail.kt index 9b21e533..315a44d5 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/VideoDetail.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/VideoDetail.kt @@ -10,8 +10,8 @@ import java.util.Date data class VideoDetail( val bvid: String, - val aid: Int, - val cid: Int, + val aid: Long, + val cid: Long, val cover: String, val title: String, val publishDate: Date, @@ -31,8 +31,8 @@ data class VideoDetail( companion object { fun fromViewReply(viewReply: ViewReply) = VideoDetail( bvid = viewReply.bvid, - aid = viewReply.arc.aid.toInt(), - cid = viewReply.arc.firstCid.toInt(), + aid = viewReply.arc.aid, + cid = viewReply.arc.firstCid, cover = viewReply.arc.pic, title = viewReply.arc.title, publishDate = Date(viewReply.arc.pubdate * 1000L), @@ -112,12 +112,12 @@ data class VideoDetail( data class History( val progress: Int, - val lastPlayedCid: Int + val lastPlayedCid: Long ) { companion object { fun fromHistory(history: bilibili.app.view.v1.History) = History( progress = history.progress.toInt(), - lastPlayedCid = history.cid.toInt() + lastPlayedCid = history.cid ) } } diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/VideoPage.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/VideoPage.kt index 95f92fc8..9163371d 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/VideoPage.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/VideoPage.kt @@ -3,7 +3,7 @@ package dev.aaa1115910.biliapi.entity.video import bilibili.app.view.v1.ViewPage data class VideoPage( - var cid: Int, + var cid: Long, val index: Int, val title: String, val duration: Int, @@ -11,7 +11,7 @@ data class VideoPage( ) { companion object { fun fromViewPage(viewPage: ViewPage) = VideoPage( - cid = viewPage.page.cid.toInt(), + cid = viewPage.page.cid, index = viewPage.page.page, title = viewPage.page.part, duration = viewPage.page.duration.toInt(), diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/season/Episode.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/season/Episode.kt index b457ed32..5d66d969 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/season/Episode.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/entity/video/season/Episode.kt @@ -19,9 +19,9 @@ import dev.aaa1115910.biliapi.entity.video.Dimension */ data class Episode( val id: Int, - val aid: Int, + val aid: Long, val bvid: String, - val cid: Int, + val cid: Long, val epid: Int? = null, val title: String, val longTitle: String, @@ -32,9 +32,9 @@ data class Episode( companion object { fun fromEpisode(episode: bilibili.app.view.v1.Episode) = Episode( id = episode.id.toInt(), - aid = episode.aid.toInt(), + aid = episode.aid, bvid = episode.bvid, - cid = episode.cid.toInt(), + cid = episode.cid, title = episode.title, longTitle = episode.title, cover = episode.cover, @@ -57,7 +57,7 @@ data class Episode( fun fromEpisode(episode: dev.aaa1115910.biliapi.http.entity.season.Episode) = Episode( id = episode.id, - aid = episode.aid.toInt(), + aid = episode.aid, cid = episode.cid, bvid = episode.bvid, cover = episode.cover, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliHttpApi.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliHttpApi.kt index 96815d8e..50a6f5ea 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliHttpApi.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliHttpApi.kt @@ -165,7 +165,7 @@ object BiliHttpApi { * 获取视频超详细信息 */ suspend fun getVideoDetail( - av: Int? = null, + av: Long? = null, bv: String? = null, sessData: String? = null ): BiliResponse = client.get("/x/web-interface/view/detail") { @@ -178,9 +178,9 @@ object BiliHttpApi { * 获取视频流 */ suspend fun getVideoPlayUrl( - av: Int? = null, + av: Long? = null, bv: String? = null, - cid: Int, + cid: Long, qn: Int? = null, fnval: Int? = null, fnver: Int? = null, @@ -210,10 +210,10 @@ object BiliHttpApi { * 获取剧集视频流 */ suspend fun getPgcVideoPlayUrl( - av: Int? = null, + av: Long? = null, bv: String? = null, epid: Int? = null, - cid: Int? = null, + cid: Long? = null, qn: Int? = null, fnval: Int? = null, fnver: Int? = null, @@ -247,7 +247,7 @@ object BiliHttpApi { * 通过[cid]获取视频弹幕 */ suspend fun getDanmakuXml( - cid: Int, + cid: Long, sessData: String = "" ): DanmakuResponse { val xmlChannel = client.get("/x/v1/dm/list.so") { @@ -396,7 +396,7 @@ object BiliHttpApi { suspend fun getAllFavoriteFoldersInfo( mid: Long, type: Int = 0, - rid: Int? = null, + rid: Long? = null, accessKey: String? = null, sessData: String? = null ): BiliResponse = client.get("/x/v3/fav/folder/created/list-all") { @@ -482,7 +482,7 @@ object BiliHttpApi { suspend fun sendHeartbeat( avid: Long? = null, bvid: String? = null, - cid: Int? = null, + cid: Long? = null, epid: Int? = null, sid: Int? = null, mid: Long? = null, @@ -521,7 +521,7 @@ object BiliHttpApi { suspend fun sendHeartbeat( avid: Long? = null, bvid: String? = null, - cid: Int? = null, + cid: Long? = null, epid: Int? = null, sid: Int? = null, mid: Long? = null, @@ -559,8 +559,8 @@ object BiliHttpApi { * 获取视频[avid]的[cid]视频更多信息,例如播放进度 */ suspend fun getVideoMoreInfo( - avid: Int, - cid: Int, + avid: Long, + cid: Long, sessData: String ): BiliResponse = client.get("/x/player/v2") { parameter("aid", avid) @@ -576,7 +576,7 @@ object BiliHttpApi { * @param sessData SESSDATA */ suspend fun sendVideoLike( - avid: Int? = null, + avid: Long? = null, bvid: String? = null, like: Boolean = true, csrf: String, @@ -601,7 +601,7 @@ object BiliHttpApi { * 检查视频[avid]或[bvid]是否已点赞 */ suspend fun checkVideoLiked( - avid: Int? = null, + avid: Long? = null, bvid: String? = null, sessData: String ): Boolean { @@ -625,7 +625,7 @@ object BiliHttpApi { * @param sessData SESSDATA */ suspend fun sendVideoCoin( - avid: Int? = null, + avid: Long? = null, bvid: String? = null, multiply: Int = 1, like: Boolean = false, @@ -652,7 +652,7 @@ object BiliHttpApi { * 检查视频[avid]或[bvid]是否已投币 */ suspend fun checkVideoSentCoin( - avid: Int? = null, + avid: Long? = null, bvid: String? = null, sessData: String ): Boolean { @@ -671,7 +671,7 @@ object BiliHttpApi { * 为视频[avid]添加到[addMediaIds]或从[delMediaIds]移除 */ suspend fun setVideoToFavorite( - avid: Int, + avid: Long, type: Int = 2, addMediaIds: List = listOf(), delMediaIds: List = listOf(), @@ -704,7 +704,7 @@ object BiliHttpApi { * 检查视频[avid]是否已收藏 */ suspend fun checkVideoFavoured( - avid: Int, + avid: Long, accessKey: String? = null, sessData: String? = null ): Boolean { @@ -752,7 +752,7 @@ object BiliHttpApi { suspend fun getAppUserSpaceVideos( mid: Long, - lastAvid: Int, + lastAvid: Long, order: String = "pubdate", accessKey: String ): BiliResponse = @@ -912,7 +912,7 @@ object BiliHttpApi { * 获取视频[avid]/[bvid]的视频标签[Tag] */ suspend fun getVideoTags( - avid: Int? = null, + avid: Long? = null, bvid: String? = null, sessData: String = "" ): BiliResponse> = client.get("/x/tag/archive/tags") { diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliHttpProxyApi.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliHttpProxyApi.kt index c5b432d2..879e496a 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliHttpProxyApi.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliHttpProxyApi.kt @@ -65,10 +65,10 @@ object BiliHttpProxyApi { } suspend fun getPgcVideoPlayUrl( - av: Int? = null, + av: Long? = null, bv: String? = null, epid: Int? = null, - cid: Int? = null, + cid: Long? = null, qn: Int? = null, fnval: Int? = null, fnver: Int? = null, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliPassportHttpApi.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliPassportHttpApi.kt index f85f87c8..d3cac524 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliPassportHttpApi.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliPassportHttpApi.kt @@ -136,7 +136,7 @@ object BiliPassportHttpApi { * @param statistics 一般固定为{"appId":1,"platform":3,"version":"7.27.0","abtest":""} */ suspend fun sendSms( - cid: Int, + cid: Long, tel: Long, loginSessionId: String, recaptchaToken: String? = null, @@ -166,7 +166,7 @@ object BiliPassportHttpApi { }.body() suspend fun loginWithSms( - cid: Int, + cid: Long, tel: Long, loginSessionId: String, code: Int, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliPlusHttpApi.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliPlusHttpApi.kt index 8f183c3e..56b6b44b 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliPlusHttpApi.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/BiliPlusHttpApi.kt @@ -57,7 +57,7 @@ object BiliPlusHttpApi { } suspend fun view( - aid: Int, + aid: Long, update: Boolean = true, accessKey: String? = null ): BiliResponse { @@ -85,7 +85,7 @@ object BiliPlusHttpApi { } suspend fun getSeasonIdByAvid( - aid: Int + aid: Long ): Int? { return runCatching { view(aid).getResponseData().bangumi?.seasonId?.toInt() diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/biliplus/View.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/biliplus/View.kt index a5f01162..5aecbb4b 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/biliplus/View.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/biliplus/View.kt @@ -7,7 +7,7 @@ import kotlinx.serialization.json.JsonElement @Serializable data class View( - val aid: Int, + val aid: Long, val author: String, val bangumi: Bangumi? = null, val coins: Int, @@ -59,7 +59,7 @@ data class View( @Serializable data class ListItem( - val cid: Int, + val cid: Long, val page: Int, val part: String, val type: String, @@ -68,9 +68,9 @@ data class View( @Serializable data class V2AppApi( - val aid: Int, + val aid: Long, val bvid: String, - val cid: Int, + val cid: Long, @SerialName("cm_config") val cmConfig: CmConfig, val config: Config, @@ -260,7 +260,7 @@ data class View( @Serializable data class Page( - val cid: Int, + val cid: Long, val dimension: Dimension? = null, val dmlink: String? = null, @SerialName("download_subtitle") @@ -284,10 +284,10 @@ data class View( @Serializable data class Paster( - val aid: Int, + val aid: Long, @SerialName("allow_jump") val allowJump: Int, - val cid: Int, + val cid: Long, val duration: Int, val type: Int, val url: String @@ -341,7 +341,7 @@ data class View( @Serializable data class Stat( - val aid: Int, + val aid: Long, val coin: Int, val danmaku: Int, val dislike: Int, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/history/HistoryData.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/history/HistoryData.kt index 4d3628ba..050b39ad 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/history/HistoryData.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/history/HistoryData.kt @@ -124,11 +124,11 @@ data class HistoryItem( */ @Serializable data class HistoryInfo( - val oid: Int, + val oid: Long, val epid: Int, val bvid: String, val page: Int, - val cid: Int, + val cid: Long, val part: String, val business: String, val dt: Int diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/home/RcmdIndexData.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/home/RcmdIndexData.kt index e6299a4e..5bb4dbc9 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/home/RcmdIndexData.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/home/RcmdIndexData.kt @@ -120,7 +120,7 @@ data class RcmdIndexData( ) { @Serializable data class Args( - val aid: Int? = null, + val aid: Long? = null, val rid: Int? = null, val rname: String? = null, val tid: Int? = null, @@ -153,8 +153,8 @@ data class RcmdIndexData( @Serializable data class PlayerArgs( - val aid: Int, - val cid: Int, + val aid: Long, + val cid: Long, val duration: Int, val type: String ) diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/home/RcmdTopData.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/home/RcmdTopData.kt index 912df31a..ff5758c6 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/home/RcmdTopData.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/home/RcmdTopData.kt @@ -29,12 +29,12 @@ data class RcmdTopData( @SerialName("business_info") val businessInfo: BusinessInfo?, val bvid: String, - val cid: Int, + val cid: Long, val duration: Int, @SerialName("enable_vt") val enableVt: Int, val goto: String, - val id: Int, + val id: Long, @SerialName("is_followed") val isFollowed: Int, @SerialName("is_stock") diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/proxy/PlayUrl.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/proxy/PlayUrl.kt index e2f8ff5b..a760f620 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/proxy/PlayUrl.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/proxy/PlayUrl.kt @@ -58,7 +58,7 @@ data class ProxyWebPlayUrlData( @SerialName("last_play_time") val lastPlayTime: Int = 0, @SerialName("last_play_cid") - val lastPlayCid: Int = 0, + val lastPlaycid: Long = 0, @SerialName("clip_info_list") val clipInfoList: List = emptyList(), @SerialName("record_info") @@ -113,7 +113,7 @@ data class ProxyAppPlayUrlData( @SerialName("last_play_time") val lastPlayTime: Int = 0, @SerialName("last_play_cid") - val lastPlayCid: Int = 0, + val lastPlaycid: Long = 0, @SerialName("clip_info_list") val clipInfoList: List = emptyList(), @SerialName("record_info") diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/search/SearchResultItem.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/search/SearchResultItem.kt index 90297450..afe47f8b 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/search/SearchResultItem.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/search/SearchResultItem.kt @@ -378,7 +378,7 @@ data class SearchVideoResult( val typeName: String, @SerialName("arcurl") val arcUrl: String, - val aid: Int, + val aid: Long, val bvid: String, val title: String, val description: String, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/season/Episode.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/season/Episode.kt index 7e4285a3..cfacf441 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/season/Episode.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/season/Episode.kt @@ -48,7 +48,7 @@ data class Episode( @SerialName("badge_type") val badgeType: Int = 0, val bvid: String = "", - val cid: Int, + val cid: Long, val cover: String, val dimension: Dimension? = null, val duration: Int = 0, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/user/SpaceVideoData.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/user/SpaceVideoData.kt index adbce4a5..e104cc11 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/user/SpaceVideoData.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/user/SpaceVideoData.kt @@ -81,7 +81,7 @@ data class WebSpaceVideoData( */ @Serializable data class VListItem( - val aid: Int, + val aid: Long, val bvid: String, val author: String, val comment: Int, @@ -133,7 +133,7 @@ data class WebSpaceVideoData( @SerialName("ep_count") val epCount: Int, @SerialName("first_aid") - val firstAid: Int, + val firstAid: Long, val ptime: Int, @SerialName("ep_num") val epNum: Int @@ -224,7 +224,7 @@ data class AppSpaceVideoData( @SerialName("three_point") val threePoint: List = emptyList(), @SerialName("first_cid") - val firstCid: Int, + val firstcid: Long, @SerialName("cursor_attr") val cursorAttr: CursorAttr, @SerialName("icon_type") diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/PlayUrlResponse.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/PlayUrlResponse.kt index 48364a38..04168a1f 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/PlayUrlResponse.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/PlayUrlResponse.kt @@ -87,7 +87,7 @@ data class PlayUrlData( @SerialName("last_play_time") val lastPlayTime: Int = 0, @SerialName("last_play_cid") - val lastPlayCid: Int = 0, + val lastPlaycid: Long = 0, @SerialName("clip_info_list") val clipInfoList: List = emptyList(), @SerialName("record_info") diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/RelatedVideosResponse.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/RelatedVideosResponse.kt index 2d17c2cd..d6093483 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/RelatedVideosResponse.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/RelatedVideosResponse.kt @@ -45,7 +45,7 @@ data class RelatedVideosResponse( @Serializable data class RelatedVideoInfo( val bvid: String, - val aid: Int, + val aid: Long, val videos: Int, val tid: Int, val tname: String, @@ -61,7 +61,7 @@ data class RelatedVideoInfo( val owner: VideoOwner, val stat: VideoStat, val dynamic: String, - val cid: Int, + val cid: Long, val dimension: Dimension, @SerialName("short_link") val shortLink: String? = null, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/UgcSeason.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/UgcSeason.kt index 510c14b9..bac527a5 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/UgcSeason.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/UgcSeason.kt @@ -44,8 +44,8 @@ data class UgcSeason( @SerialName("section_id") val sectionId: Int, val id: Int, - val aid: Int, - val cid: Int, + val aid: Long, + val cid: Long, val title: String, val attribute: Int, val arc: Arc, @@ -54,7 +54,7 @@ data class UgcSeason( ) { @Serializable data class Arc( - val aid: Int, + val aid: Long, val videos: Int, @SerialName("type_id") val typeId: Int, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/VideoInfo.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/VideoInfo.kt index c6d1bd07..6ac9d461 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/VideoInfo.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/VideoInfo.kt @@ -61,7 +61,7 @@ import kotlinx.serialization.json.jsonPrimitive @Serializable data class VideoInfo( val bvid: String, - val aid: Int, + val aid: Long, val videos: Int, val tid: Int, val tname: String, @@ -82,7 +82,7 @@ data class VideoInfo( val owner: VideoOwner, val stat: VideoStat, val dynamic: String, - val cid: Int, + val cid: Long, val dimension: Dimension, val premiere: Premiere? = null, @SerialName("teenage_mode") @@ -233,7 +233,7 @@ data class VideoOwner( */ @Serializable data class VideoStat( - val aid: Int = 0, + val aid: Long = 0, val view: Int = 0, val danmaku: Int = 0, val reply: Int = 0, @@ -288,7 +288,7 @@ data class Premiere( */ @Serializable data class VideoPage( - val cid: Int, + val cid: Long, val page: Int, val from: String, val part: String, @@ -318,7 +318,7 @@ data class HonorReply( */ @Serializable data class HonorReplyItem( - val aid: Int, + val aid: Long, val type: Int, val desc: String, @SerialName("weekly_recommend_num") diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/VideoMoreInfo.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/VideoMoreInfo.kt index 25229de2..e55df02f 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/VideoMoreInfo.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/http/entity/video/VideoMoreInfo.kt @@ -50,13 +50,13 @@ import kotlinx.serialization.json.JsonArray */ @Serializable data class VideoMoreInfo( - val aid: Int, + val aid: Long, val bvid: String, @SerialName("allow_bp") val allowBp: Boolean, @SerialName("no_share") val noShare: Boolean, - val cid: Int, + val cid: Long, @SerialName("max_limit") val maxLimit: Int, @SerialName("page_no") @@ -84,7 +84,7 @@ data class VideoMoreInfo( @SerialName("last_play_time") val lastPlayTime: Int, @SerialName("last_play_cid") - val lastPlayCid: Int, + val lastPlayCid: Long, @SerialName("now_time") val nowTime: Int, @SerialName("online_count") @@ -150,7 +150,7 @@ data class VideoMoreInfo( */ @Serializable data class DmMask( - val cid: Int, + val cid: Long, val plat: Int, val fps: Int, val time: Int, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/FavoriteRepository.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/FavoriteRepository.kt index 9e793e45..804430ce 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/FavoriteRepository.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/FavoriteRepository.kt @@ -10,7 +10,7 @@ class FavoriteRepository( private val authRepository: AuthRepository ) { suspend fun checkVideoFavoured( - aid: Int, + aid: Long, preferApiType: ApiType = ApiType.Web ): Boolean { return when (preferApiType) { @@ -27,7 +27,7 @@ class FavoriteRepository( } suspend fun addVideoToFavoriteFolder( - aid: Int, + aid: Long, addMediaIds: List, preferApiType: ApiType = ApiType.Web ) { @@ -50,7 +50,7 @@ class FavoriteRepository( } suspend fun delVideoFromFavoriteFolder( - aid: Int, + aid: Long, delMediaIds: List, preferApiType: ApiType = ApiType.Web ) { @@ -73,7 +73,7 @@ class FavoriteRepository( } suspend fun updateVideoToFavoriteFolder( - aid: Int, + aid: Long, addMediaIds: List, delMediaIds: List, preferApiType: ApiType = ApiType.Web @@ -101,7 +101,7 @@ class FavoriteRepository( suspend fun getAllFavoriteFolderMetadataList( mid: Long, type: FavoriteItemType = FavoriteItemType.Video, - rid: Int? = null, + rid: Long? = null, preferApiType: ApiType = ApiType.Web ): List { val userFavoriteFoldersData = when (preferApiType) { diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/SearchRepository.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/SearchRepository.kt index 52230d1c..19bacff3 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/SearchRepository.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/SearchRepository.kt @@ -306,7 +306,7 @@ data class SearchTypeResult( interface SearchTypeResultItem data class Video( - val aid: Int, + val aid: Long, val bvid: String, val title: String, val cover: String, @@ -330,7 +330,7 @@ data class SearchTypeResult( fun fromSearchVideoCard(video: bilibili.polymer.app.search.v1.Item) = Video( - aid = video.param.toInt(), + aid = video.param.toLong(), bvid = video.av.share.video.bvid, title = video.av.title, cover = video.av.cover, diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/VideoDetailRepository.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/VideoDetailRepository.kt index fa642730..7271f965 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/VideoDetailRepository.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/VideoDetailRepository.kt @@ -22,7 +22,7 @@ class VideoDetailRepository( }.getOrNull() suspend fun getVideoDetail( - aid: Int, + aid: Long, preferApiType: ApiType = ApiType.Web ): VideoDetail { return when (preferApiType) { diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepository.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepository.kt index 46706790..7eba1b40 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepository.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepository.kt @@ -40,8 +40,8 @@ class VideoPlayRepository( suspend fun getPlayData( - aid: Int, - cid: Int, + aid: Long, + cid: Long, preferCodec: CodeType = CodeType.NoCode, preferApiType: ApiType = ApiType.Web ): PlayData { @@ -79,8 +79,8 @@ class VideoPlayRepository( } suspend fun getPgcPlayData( - aid: Int, - cid: Int, + aid: Long, + cid: Long, epid: Int, preferCodec: CodeType = CodeType.NoCode, preferApiType: ApiType = ApiType.Web, @@ -142,8 +142,8 @@ class VideoPlayRepository( } suspend fun getSubtitle( - aid: Int, - cid: Int, + aid: Long, + cid: Long, preferApiType: ApiType = ApiType.Web ): List { return when (preferApiType) { @@ -173,8 +173,8 @@ class VideoPlayRepository( } suspend fun sendHeartbeat( - aid: Int, - cid: Int, + aid: Long, + cid: Long, time: Int, type: HeartbeatVideoType = HeartbeatVideoType.Video, subType: Int? = null, diff --git a/bili-api/src/test/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepositoryTest.kt b/bili-api/src/test/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepositoryTest.kt index 654e1c0e..8d4d164a 100644 --- a/bili-api/src/test/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepositoryTest.kt +++ b/bili-api/src/test/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepositoryTest.kt @@ -277,7 +277,7 @@ class VideoPlayRepositoryTest { @Test fun `get region limited pgc play data`() = runBlocking { - val cid = 1199794768 + val cid = 1199794768L val epid = 763396 val enableProxy = true val proxyArea = "hk" From 158759e6e3c2d22cc625a6aa60d4b515cab5c60a Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Tue, 14 May 2024 19:49:05 +0800 Subject: [PATCH 18/19] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20Protobuf=20v26.x=20?= =?UTF-8?q?=E7=A0=B4=E5=9D=8F=E6=80=A7=E6=9B=B4=E6=96=B0=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E8=A7=A3=E6=9E=90=E9=94=99=E8=AF=AF=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在生成的代码中 com.google.rpc.Status 继承 com.google.protobuf.GeneratedMessageV3,但 GeneratedMessageV3 却被移除,导致 Status 无法正常解析 https://protobuf.dev/news/2023-12-05/ --- .../kotlin/dev/aaa1115910/biliapi/grpc/utils/StatusExtends.kt | 3 ++- .../aaa1115910/biliapi/repositories/VideoPlayRepositoryTest.kt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/grpc/utils/StatusExtends.kt b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/grpc/utils/StatusExtends.kt index 1bfe4432..c09b7a05 100644 --- a/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/grpc/utils/StatusExtends.kt +++ b/bili-api/src/main/kotlin/dev/aaa1115910/biliapi/grpc/utils/StatusExtends.kt @@ -1,7 +1,8 @@ package dev.aaa1115910.biliapi.grpc.utils +import bilibili.rpc.Status import com.google.protobuf.Message -import com.google.rpc.Status +//import com.google.rpc.Status import io.grpc.Metadata import io.grpc.StatusException diff --git a/bili-api/src/test/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepositoryTest.kt b/bili-api/src/test/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepositoryTest.kt index 8d4d164a..6ab35de5 100644 --- a/bili-api/src/test/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepositoryTest.kt +++ b/bili-api/src/test/kotlin/dev/aaa1115910/biliapi/repositories/VideoPlayRepositoryTest.kt @@ -1,6 +1,7 @@ package dev.aaa1115910.biliapi.repositories -import com.google.rpc.Status +import bilibili.rpc.Status +//import com.google.rpc.Status import dev.aaa1115910.biliapi.entity.ApiType import dev.aaa1115910.biliapi.entity.video.HeartbeatVideoType import dev.aaa1115910.biliapi.grpc.utils.getDetail From 6414d6a8c8409df4aa960239723493a1eedf030d Mon Sep 17 00:00:00 2001 From: aaa1115910 Date: Tue, 14 May 2024 20:10:14 +0800 Subject: [PATCH 19/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20ci?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用 gradle/actions/setup-gradle 提交依赖项关系图 --- .github/workflows/alpha.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/alpha.yml b/.github/workflows/alpha.yml index 92bf3d91..1926a94c 100644 --- a/.github/workflows/alpha.yml +++ b/.github/workflows/alpha.yml @@ -25,6 +25,11 @@ jobs: java-version: '17' distribution: 'temurin' + - name: Setup Gradle to generate and submit dependency graphs + uses: gradle/actions/setup-gradle@v3 + with: + dependency-graph: generate-and-submit + - name: Write google-services.json env: DATA: ${{ secrets.GOOGLE_SERVICES_JSON }}