From 0f6cf2335c34d55b8911a23f6f048415aaac2755 Mon Sep 17 00:00:00 2001 From: storytellerF <34095089+storytellerF@users.noreply.github.com> Date: Sat, 26 Aug 2023 19:45:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AF=BC=E5=85=A5=20?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=97=A0=E7=94=A8=E6=96=87=E4=BB=B6=EF=BC=9B?= =?UTF-8?q?=E6=8F=90=E5=8F=96playVideo=20=E4=BD=9C=E4=B8=BA=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/storyteller_f/bi/App.kt | 97 --------------- .../main/java/com/storyteller_f/bi/Common.kt | 63 +++++++++- .../java/com/storyteller_f/bi/MainActivity.kt | 77 +----------- .../com/storyteller_f/bi/VideoActivity.kt | 15 +++ .../bi/components/BottomNavigation.kt | 1 - .../bi/components/FavoriteDetailPage.kt | 5 +- .../bi/components/HomeNavigation.kt | 4 +- .../storyteller_f/bi/components/SearchPage.kt | 23 ++-- .../bi/unstable/PlayerDelegate.kt | 112 +++++++++++++++++- bilimiao2 | 2 +- 10 files changed, 206 insertions(+), 193 deletions(-) delete mode 100644 app/src/main/java/com/storyteller_f/bi/components/BottomNavigation.kt diff --git a/app/src/main/java/com/storyteller_f/bi/App.kt b/app/src/main/java/com/storyteller_f/bi/App.kt index 431c156..646acb8 100644 --- a/app/src/main/java/com/storyteller_f/bi/App.kt +++ b/app/src/main/java/com/storyteller_f/bi/App.kt @@ -37,100 +37,3 @@ class App : Application() { readUserInfo() } } - -suspend fun BasePlayerRepository.subtitleMediaSources( - context: Context -): List { - return subtitleConfigurations(context).map { - SingleSampleMediaSource.Factory(DefaultDataSource.Factory(context)) - .createMediaSource(it, C.TIME_UNSET) - } -} - -suspend fun BasePlayerRepository.subtitleConfigurations( - context: Context -): List { - - val subtitles = getSubtitles() - - val pairs = subtitles.mapNotNull { info: SubtitleSourceInfo -> - val file = File(context.cacheDir, "/subtitle/$id/${info.lan}.srt") - val parent = file.parentFile - when { - parent == null -> null - !parent.exists() && !parent.mkdirs() -> null - file.exists() -> file to info to null - !file.createNewFile() -> null - else -> { - val res = MiaoHttp.request { - url = UrlUtil.autoHttps(info.subtitle_url) - }.awaitCall().gson() - file to info to res - } - } - } - val lanList = pairs.map { it.first.second.lan } - val infoList = pairs.mapNotNull { - it.second - } - - val configurations = pairs.map { (it, jInfo) -> - val (file, info) = it - if (jInfo != null) { - writeToFile(jInfo, file) - } - MediaItem.SubtitleConfiguration.Builder(file.toUri()) - .setMimeType(MimeTypes.APPLICATION_SUBRIP) - .setSelectionFlags(C.SELECTION_FLAG_DEFAULT) - .setLabel(info.lan_doc) - .setId(info.id) - .setRoleFlags(C.ROLE_FLAG_SUBTITLE) - .setLanguage(info.lan).build() - } - val file = File(context.cacheDir, "subtitle/$id/mix.srt") - val parentFile = file.parentFile - if (pairs.size == 2 && infoList.size == 2 && subtitles.size == 2 && lanList.any { - it.contains("zh") - } && lanList.any { - it.contains( - "en" - ) - } && parentFile != null && (parentFile.exists() || parentFile.mkdirs()) && (file.exists() || withContext(Dispatchers.IO) { - file.createNewFile() - }) - ) { - val first = infoList.first() - val jsonInfo = infoList.last() - - writeToFile(first, file) { it, i -> - "${it.content}\n${jsonInfo.body[i].content}" - } - return configurations + MediaItem.SubtitleConfiguration.Builder(file.toUri()) - .setMimeType(MimeTypes.APPLICATION_SUBRIP) - .setSelectionFlags(C.SELECTION_FLAG_DEFAULT) - .setLabel("mix") - .setRoleFlags(C.ROLE_FLAG_SUBTITLE).build() - } - return configurations -} - -private suspend fun writeToFile( - jInfo: SubtitleJsonInfo, - file: File, - c: (SubtitleJsonInfo.ItemInfo, Int) -> String = { it, _ -> it.content } -) { - val content = jInfo.body.mapIndexed { index, itemInfo -> - val toDuration = PlayerDelegate.formatDuration( - itemInfo.to - ) - val fromDuration = PlayerDelegate.formatDuration(itemInfo.from) - """ -${index + 1} -$fromDuration --> $toDuration -${c(itemInfo, index)} - """.trimIndent() - }.joinToString("\n\n") - withContext(Dispatchers.IO) { - file.writeText(content) - } -} diff --git a/app/src/main/java/com/storyteller_f/bi/Common.kt b/app/src/main/java/com/storyteller_f/bi/Common.kt index d56ab5c..f29aa6d 100644 --- a/app/src/main/java/com/storyteller_f/bi/Common.kt +++ b/app/src/main/java/com/storyteller_f/bi/Common.kt @@ -1,11 +1,18 @@ package com.storyteller_f.bi +import android.content.Context +import android.content.Intent +import android.graphics.Bitmap +import android.graphics.Color +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.pullrefresh.PullRefreshIndicator import androidx.compose.material.pullrefresh.pullRefresh import androidx.compose.material.pullrefresh.rememberPullRefreshState +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -17,6 +24,7 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalView import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider @@ -25,6 +33,9 @@ import androidx.lifecycle.viewmodel.MutableCreationExtras import androidx.paging.LoadState import androidx.paging.compose.LazyPagingItems import com.a10miaomiao.bilimiao.comm.entity.ResultInfo2 +import com.google.zxing.BarcodeFormat +import com.google.zxing.EncodeHintType +import com.google.zxing.qrcode.QRCodeWriter import com.storyteller_f.bi.components.BangumiViewModel import com.storyteller_f.bi.components.CommentId import com.storyteller_f.bi.components.CommentReplyViewModel @@ -40,8 +51,11 @@ import com.storyteller_f.bi.components.VideoViewModel import com.storyteller_f.bi.components.error import com.storyteller_f.bi.components.loaded import com.storyteller_f.bi.components.loading +import com.storyteller_f.bi.unstable.userInfo import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import java.util.Collections +import java.util.stream.IntStream sealed class LoadingState { class Loading(val state: String) : LoadingState() @@ -206,4 +220,51 @@ inline fun request( val state = handler.state val data = handler.data request(state, data, service) -} \ No newline at end of file +} + + +@Composable +fun StandBy(modifier: Modifier, me: @Composable () -> Unit) { + val view = LocalView.current + if (view.isInEditMode) { + Box(modifier.background(MaterialTheme.colorScheme.primaryContainer)) + } else { + me() + } +} + + +fun String.createQRImage(width: Int, height: Int): Bitmap { + val bitMatrix = QRCodeWriter().encode( + this, + BarcodeFormat.QR_CODE, + width, + height, + Collections.singletonMap(EncodeHintType.CHARACTER_SET, "utf-8") + ) + return Bitmap.createBitmap( + IntStream.range(0, height).flatMap { h: Int -> + IntStream.range(0, width).map { w: Int -> + if (bitMatrix[w, h] + ) Color.BLACK else Color.WHITE + } + }.toArray(), + width, height, Bitmap.Config.ARGB_8888 + ) +} + +@Composable +fun UserAware(login: () -> Unit = {}, content: @Composable () -> Unit) { + val u by userInfo.observeAsState() + if (u == null) { + OneCenter { + Button(onClick = { + login() + }) { + Text(text = "login") + } + } + } else { + content() + } +} diff --git a/app/src/main/java/com/storyteller_f/bi/MainActivity.kt b/app/src/main/java/com/storyteller_f/bi/MainActivity.kt index 8b1f0a7..8d5427f 100644 --- a/app/src/main/java/com/storyteller_f/bi/MainActivity.kt +++ b/app/src/main/java/com/storyteller_f/bi/MainActivity.kt @@ -1,29 +1,21 @@ package com.storyteller_f.bi -import android.content.Context import android.content.Intent -import android.graphics.Bitmap -import android.graphics.Color import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.displayCutoutPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding -import androidx.compose.material3.Button -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.NavigationRail import androidx.compose.material3.NavigationRailItem import androidx.compose.material3.Surface -import androidx.compose.material3.Text import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass -import androidx.compose.runtime.Composable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState @@ -33,7 +25,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalView import androidx.compose.ui.unit.dp import androidx.core.view.WindowCompat import androidx.navigation.NavDestination.Companion.hierarchy @@ -41,9 +32,6 @@ import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.compose.NavHost import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController -import com.google.zxing.BarcodeFormat -import com.google.zxing.EncodeHintType -import com.google.zxing.qrcode.QRCodeWriter import com.storyteller_f.bi.components.HomeNavigation import com.storyteller_f.bi.components.NavItemIcon import com.storyteller_f.bi.components.Screen @@ -52,8 +40,6 @@ import com.storyteller_f.bi.components.VideoPage import com.storyteller_f.bi.components.homeNav import com.storyteller_f.bi.ui.theme.BiTheme import com.storyteller_f.bi.unstable.userInfo -import java.util.Collections -import java.util.stream.IntStream class SideVideo(val id: String, val kid: String, val business: String, val progress: Long) @@ -103,9 +89,9 @@ class MainActivity : ComponentActivity() { val wideMode = calculateWindowSizeClass.widthSizeClass != WindowWidthSizeClass.Compact - val openVideo: (String, String, String, Long) -> Unit = { kid, oid, business, progress -> + val openVideo: (String?, String?, String, Long) -> Unit = { kid, oid, business, progress -> if (wideMode) { - adaptiveVideo = SideVideo(oid, kid, business, progress) + adaptiveVideo = SideVideo(oid!!, kid!!, business, progress) } else { context.playVideo(kid, oid, business, progress) } @@ -167,62 +153,3 @@ class MainActivity : ComponentActivity() { } } - -@Composable -fun UserAware(login: () -> Unit = {}, content: @Composable () -> Unit) { - val u by userInfo.observeAsState() - if (u == null) { - OneCenter { - Button(onClick = { - login() - }) { - Text(text = "login") - } - } - } else { - content() - } -} - -@Composable -fun StandBy(modifier: Modifier, me: @Composable () -> Unit) { - val view = LocalView.current - if (view.isInEditMode) { - Box(modifier.background(MaterialTheme.colorScheme.primaryContainer)) - } else { - me() - } -} - - -fun String.createQRImage(width: Int, height: Int): Bitmap { - val bitMatrix = QRCodeWriter().encode( - this, - BarcodeFormat.QR_CODE, - width, - height, - Collections.singletonMap(EncodeHintType.CHARACTER_SET, "utf-8") - ) - return Bitmap.createBitmap( - IntStream.range(0, height).flatMap { h: Int -> - IntStream.range(0, width).map { w: Int -> - if (bitMatrix[w, h] - ) Color.BLACK else Color.WHITE - } - }.toArray(), - width, height, Bitmap.Config.ARGB_8888 - ) -} - -fun Context.playVideo(kid: String?, oid: String?, business: String, progress: Long = 0L) { - startActivity( - Intent( - this, - VideoActivity::class.java - ).apply { - putExtra("videoId", oid) - putExtra("extra", kid) - putExtra("progress", progress) - putExtra("business", business) - }) -} \ No newline at end of file diff --git a/app/src/main/java/com/storyteller_f/bi/VideoActivity.kt b/app/src/main/java/com/storyteller_f/bi/VideoActivity.kt index 5666b9d..4d3c59f 100644 --- a/app/src/main/java/com/storyteller_f/bi/VideoActivity.kt +++ b/app/src/main/java/com/storyteller_f/bi/VideoActivity.kt @@ -1,5 +1,7 @@ package com.storyteller_f.bi +import android.content.Context +import android.content.Intent import android.content.pm.ActivityInfo import android.content.res.Configuration import android.os.Bundle @@ -54,4 +56,17 @@ class VideoActivity : ComponentActivity() { companion object { private const val TAG = "VideoActivity" } +} + +fun Context.playVideo(kid: String?, oid: String?, business: String, progress: Long = 0L) { + startActivity( + Intent( + this, + VideoActivity::class.java + ).apply { + putExtra("videoId", oid) + putExtra("extra", kid) + putExtra("progress", progress) + putExtra("business", business) + }) } \ No newline at end of file diff --git a/app/src/main/java/com/storyteller_f/bi/components/BottomNavigation.kt b/app/src/main/java/com/storyteller_f/bi/components/BottomNavigation.kt deleted file mode 100644 index 21f1ca1..0000000 --- a/app/src/main/java/com/storyteller_f/bi/components/BottomNavigation.kt +++ /dev/null @@ -1 +0,0 @@ -package com.storyteller_f.bi.components diff --git a/app/src/main/java/com/storyteller_f/bi/components/FavoriteDetailPage.kt b/app/src/main/java/com/storyteller_f/bi/components/FavoriteDetailPage.kt index a0b554d..6f0a527 100644 --- a/app/src/main/java/com/storyteller_f/bi/components/FavoriteDetailPage.kt +++ b/app/src/main/java/com/storyteller_f/bi/components/FavoriteDetailPage.kt @@ -29,8 +29,7 @@ import com.storyteller_f.bi.playVideo object FavoriteIdKey : CreationExtras.Key @Composable -fun FavoriteDetailPage(id: String) { - val current = LocalContext.current +fun FavoriteDetailPage(id: String, playVideo: (String?, String?, String, Long) -> Unit) { val detailViewModel = viewModel( factory = defaultFactory, extras = MutableCreationExtras().apply { @@ -51,7 +50,7 @@ fun FavoriteDetailPage(id: String) { item?.title.orEmpty(), item?.upper?.name.orEmpty() ) { - current.playVideo(item?.id, item?.id, "archive", 0) + playVideo(item?.id, item?.id, "archive", 0) } } } diff --git a/app/src/main/java/com/storyteller_f/bi/components/HomeNavigation.kt b/app/src/main/java/com/storyteller_f/bi/components/HomeNavigation.kt index fef8b49..9c746d7 100644 --- a/app/src/main/java/com/storyteller_f/bi/components/HomeNavigation.kt +++ b/app/src/main/java/com/storyteller_f/bi/components/HomeNavigation.kt @@ -57,7 +57,7 @@ fun NavItemIcon(screen: Screen) { fun NavGraphBuilder.homeNav( selectRoute: (String) -> Unit, login: () -> Unit = {}, - openVideo: (String, String, String, Long) -> Unit + openVideo: (String?, String?, String, Long) -> Unit ) { composable(Screen.History.route) { UserAware(login) { @@ -94,7 +94,7 @@ fun NavGraphBuilder.homeNav( ) { UserAware { FavoriteDetailPage( - id = it.arguments?.getString("id").orEmpty() + id = it.arguments?.getString("id").orEmpty(), openVideo ) } } diff --git a/app/src/main/java/com/storyteller_f/bi/components/SearchPage.kt b/app/src/main/java/com/storyteller_f/bi/components/SearchPage.kt index a01494c..508344f 100644 --- a/app/src/main/java/com/storyteller_f/bi/components/SearchPage.kt +++ b/app/src/main/java/com/storyteller_f/bi/components/SearchPage.kt @@ -1,6 +1,5 @@ package com.storyteller_f.bi.components -import android.content.Context import android.widget.Toast import androidx.activity.compose.BackHandler import androidx.compose.foundation.ExperimentalFoundationApi @@ -75,7 +74,6 @@ import com.bumptech.glide.integration.compose.GlideImage import com.storyteller_f.bi.StandBy import com.storyteller_f.bi.StateView import com.storyteller_f.bi.defaultFactory -import com.storyteller_f.bi.playVideo import com.storyteller_f.bi.ui.theme.BiTheme import com.storyteller_f.bi.unstable.logout import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -89,6 +87,7 @@ fun SearchPage( userInfo: UserInfo? = null, dockMode: Boolean = false, noMiddleState: Boolean = false, + playVideo: (String?, String?, String, Long) -> Unit = { _, _, _, _ -> }, login: () -> Unit = {}, back: () -> Unit = {} ) { @@ -131,7 +130,7 @@ fun SearchPage( Text(text = "search") } val content: @Composable (ColumnScope.() -> Unit) = { - SearchContent(viewModel) + SearchContent(viewModel, playVideo) } CombinedSearchBar( dockMode, @@ -200,7 +199,8 @@ private fun CombinedSearchBar( } @Composable -@OptIn(ExperimentalGlideComposeApi::class, +@OptIn( + ExperimentalGlideComposeApi::class, ExperimentalMaterial3Api::class ) private fun HomeAvatar( @@ -223,7 +223,10 @@ private fun HomeAvatar( ) } if (showPopup) { - AlertDialog(onDismissRequest = { showPopup = false }, properties = DialogProperties(decorFitsSystemWindows = false)) { + AlertDialog( + onDismissRequest = { showPopup = false }, + properties = DialogProperties(decorFitsSystemWindows = false) + ) { Surface { AvatarContent(userInfo, login) } @@ -273,9 +276,8 @@ private fun PreviewSearchPage() { @OptIn(ExperimentalFoundationApi::class) private fun SearchContent( viewModel: VideoSearchViewModel, + playVideo: (String?, String?, String, Long) -> Unit, ) { - val current = LocalContext.current - var selected by remember { mutableIntStateOf(0) } @@ -300,9 +302,8 @@ private fun SearchContent( } } } - // current.playVideo(item?.param) HorizontalPager(state = pagerState) { - SearchPageBuilder(it, viewModel, current) + SearchPageBuilder(it, viewModel, playVideo) } } @@ -311,7 +312,7 @@ private fun SearchContent( private fun SearchPageBuilder( it: Int, viewModel: VideoSearchViewModel, - current: Context + playVideo: (String?, String?, String, Long) -> Unit ) { when (it) { 0 -> { @@ -321,7 +322,7 @@ private fun SearchPageBuilder( item?.title.orEmpty(), item?.author.orEmpty() ) { - current.playVideo(item?.param, item?.param, "archive") + playVideo(item?.param, item?.param, "archive", 0) } } } diff --git a/app/src/main/java/com/storyteller_f/bi/unstable/PlayerDelegate.kt b/app/src/main/java/com/storyteller_f/bi/unstable/PlayerDelegate.kt index 44d1cbd..c88265d 100644 --- a/app/src/main/java/com/storyteller_f/bi/unstable/PlayerDelegate.kt +++ b/app/src/main/java/com/storyteller_f/bi/unstable/PlayerDelegate.kt @@ -2,17 +2,28 @@ package com.storyteller_f.bi.unstable import android.content.Context import android.net.Uri +import androidx.core.net.toUri import com.a10miaomiao.bilimiao.comm.delegate.player.BasePlayerRepository +import com.a10miaomiao.bilimiao.comm.delegate.player.entity.SubtitleSourceInfo +import com.a10miaomiao.bilimiao.comm.entity.player.SubtitleJsonInfo +import com.a10miaomiao.bilimiao.comm.network.MiaoHttp +import com.a10miaomiao.bilimiao.comm.network.MiaoHttp.Companion.gson +import com.a10miaomiao.bilimiao.comm.utils.UrlUtil +import com.google.android.exoplayer2.C import com.google.android.exoplayer2.MediaItem import com.google.android.exoplayer2.source.ConcatenatingMediaSource import com.google.android.exoplayer2.source.MediaSource import com.google.android.exoplayer2.source.MergingMediaSource import com.google.android.exoplayer2.source.ProgressiveMediaSource +import com.google.android.exoplayer2.source.SingleSampleMediaSource import com.google.android.exoplayer2.source.dash.DashMediaSource import com.google.android.exoplayer2.source.dash.manifest.DashManifestParser import com.google.android.exoplayer2.upstream.DefaultDataSource import com.google.android.exoplayer2.upstream.DefaultHttpDataSource -import com.storyteller_f.bi.subtitleMediaSources +import com.google.android.exoplayer2.util.MimeTypes +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import java.io.File class PlayerDelegate { suspend fun mediaSource(context: Context, source: BasePlayerRepository): MediaSource { @@ -104,4 +115,101 @@ class PlayerDelegate { return String.format("%02d:%02d:%02d,%03d", hours, minutes, seconds, millis) } } -} \ No newline at end of file +} +suspend fun BasePlayerRepository.subtitleMediaSources( + context: Context +): List { + return subtitleConfigurations(context).map { + SingleSampleMediaSource.Factory(DefaultDataSource.Factory(context)) + .createMediaSource(it, C.TIME_UNSET) + } +} + +suspend fun BasePlayerRepository.subtitleConfigurations( + context: Context +): List { + + val subtitles = getSubtitles() + + val pairs = subtitles.mapNotNull { info: SubtitleSourceInfo -> + val file = File(context.cacheDir, "/subtitle/$id/${info.lan}.srt") + val parent = file.parentFile + when { + parent == null -> null + !parent.exists() && !parent.mkdirs() -> null + file.exists() -> file to info to null + !file.createNewFile() -> null + else -> { + val res = MiaoHttp.request { + url = UrlUtil.autoHttps(info.subtitle_url) + }.awaitCall().gson() + file to info to res + } + } + } + val lanList = pairs.map { it.first.second.lan } + val infoList = pairs.mapNotNull { + it.second + } + + val configurations = pairs.map { (it, jInfo) -> + val (file, info) = it + if (jInfo != null) { + writeToFile(jInfo, file) + } + MediaItem.SubtitleConfiguration.Builder(file.toUri()) + .setMimeType(MimeTypes.APPLICATION_SUBRIP) + .setSelectionFlags(C.SELECTION_FLAG_DEFAULT) + .setLabel(info.lan_doc) + .setId(info.id) + .setRoleFlags(C.ROLE_FLAG_SUBTITLE) + .setLanguage(info.lan).build() + } + val file = File(context.cacheDir, "subtitle/$id/mix.srt") + val parentFile = file.parentFile + if (pairs.size == 2 && infoList.size == 2 && subtitles.size == 2 && lanList.any { + it.contains("zh") + } && lanList.any { + it.contains( + "en" + ) + } && parentFile != null && (parentFile.exists() || parentFile.mkdirs()) && (file.exists() || withContext( + Dispatchers.IO) { + file.createNewFile() + }) + ) { + val first = infoList.first() + val jsonInfo = infoList.last() + + writeToFile(first, file) { it, i -> + "${it.content}\n${jsonInfo.body[i].content}" + } + return configurations + MediaItem.SubtitleConfiguration.Builder(file.toUri()) + .setMimeType(MimeTypes.APPLICATION_SUBRIP) + .setSelectionFlags(C.SELECTION_FLAG_DEFAULT) + .setLabel("mix") + .setRoleFlags(C.ROLE_FLAG_SUBTITLE).build() + } + return configurations +} + +private suspend fun writeToFile( + jInfo: SubtitleJsonInfo, + file: File, + c: (SubtitleJsonInfo.ItemInfo, Int) -> String = { it, _ -> it.content } +) { + val content = jInfo.body.mapIndexed { index, itemInfo -> + val toDuration = PlayerDelegate.formatDuration( + itemInfo.to + ) + val fromDuration = PlayerDelegate.formatDuration(itemInfo.from) + """ +${index + 1} +$fromDuration --> $toDuration +${c(itemInfo, index)} + """.trimIndent() + }.joinToString("\n\n") + withContext(Dispatchers.IO) { + file.writeText(content) + } +} diff --git a/bilimiao2 b/bilimiao2 index a84dc5e..28bd551 160000 --- a/bilimiao2 +++ b/bilimiao2 @@ -1 +1 @@ -Subproject commit a84dc5e8d59faafb9c05810cff85f36d4249955f +Subproject commit 28bd5518a678bafa6f6a0065909977d56b359340