Skip to content

Commit

Permalink
Merge branch '10miaomiao:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
storytellerF committed Apr 28, 2023
2 parents 0ef3980 + 2a35f3c commit 9caa5e5
Show file tree
Hide file tree
Showing 30 changed files with 275 additions and 117 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ dependencies {
implementation(Libraries.foregroundCompat)
implementation(Libraries.drawer)
implementation(Libraries.modernAndroidPreferences)
implementation(Libraries.dialogX)

// implementation("com.github.li-xiaojun:XPopup:2.9.13")
// implementation("com.github.lihangleo2:ShadowLayout:3.2.4")
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/a10miaomiao/bilimiao/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ class MainActivity
windowStore.setContentInsets(
left, if (showPlayer) 0 else top, right, bottom + config.appBarTitleHeight,
)
windowStore.setBottomAppBarHeight(bottom + config.appBarHeight)
ui.mAppBar.setPadding(
left, 0, right, bottom
)
Expand All @@ -292,6 +293,7 @@ class MainActivity
windowStore.setContentInsets(
0, top, right, bottom,
)
windowStore.setBottomAppBarHeight(bottom)
ui.mAppBar.setPadding(
left, top, 0, bottom
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.net.Uri
import android.os.Build
import android.os.Handler
import android.preference.PreferenceManager
import android.util.Rational
import android.view.MenuItem
Expand Down Expand Up @@ -38,13 +39,16 @@ class PlayerController(
private val statusBarHelper by instance<StatusBarHelper>()
private val scaffoldApp get() = delegate.scaffoldApp
private val views get() = delegate.views
private val playerSourceInfo get() = delegate.playerSourceInfo
private val danmakuContext = DanmakuContext.create()

private var onlyFull = false // 仅全屏播放

private var preparedRunQueue = mutableListOf<Pair<String, Runnable>>()

private fun getFullMode(): String {
val prefs = PreferenceManager.getDefaultSharedPreferences(activity)
return prefs.getString(VideoSettingFragment.PLAYER_FULL_MODE, VideoSettingFragment.KEY_SENSOR_LANDSCAPE)!!
return prefs.getString(VideoSettingFragment.PLAYER_FULL_MODE, VideoSettingFragment.KEY_AUTO)!!
}

fun initController() = views.videoPlayer.run {
Expand Down Expand Up @@ -74,20 +78,38 @@ class PlayerController(
updatePlayerMode(activity.resources.configuration)
}

/**
* 全屏
*/
fun fullScreen(fullMode: String) {
views.videoPlayer.mode = DanmakuVideoPlayer.PlayerMode.FULL
scaffoldApp.fullScreenPlayer = true
activity.requestedOrientation = when (fullMode) {
// 横向全屏(自动旋转)
VideoSettingFragment.KEY_SENSOR_LANDSCAPE -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
// 横向全屏(固定方向1)
VideoSettingFragment.KEY_LANDSCAPE -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
// 横向全屏(固定方向2)
VideoSettingFragment.KEY_REVERSE_LANDSCAPE -> ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
// 跟随系统:不指定方向
VideoSettingFragment.KEY_UNSPECIFIED -> ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
// 跟随视频:竖向视频时为不指定方向,横向视频时候为横向全屏(自动旋转)
VideoSettingFragment.KEY_AUTO -> {
if ((playerSourceInfo?.screenProportion ?: 1f) < 1f) {
ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
} else {
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
}
}
else -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
}
statusBarHelper.isShowStatus = views.videoPlayer.topContainer.visibility == View.VISIBLE
statusBarHelper.isShowNavigation = false
}

/**
* 退出全屏
*/
fun smallScreen() {
views.videoPlayer.mode = DanmakuVideoPlayer.PlayerMode.SMALL_TOP
updatePlayerMode(activity.resources.configuration)
Expand Down Expand Up @@ -206,8 +228,9 @@ class PlayerController(
val checkMenuId = when (fullMode) {
VideoSettingFragment.KEY_SENSOR_LANDSCAPE -> R.id.full_mode_sl
VideoSettingFragment.KEY_LANDSCAPE -> R.id.full_mode_l
VideoSettingFragment.KEY_REVERSE_LANDSCAPE -> R.id.full_mode_rl
VideoSettingFragment.KEY_UNSPECIFIED -> R.id.full_mode_u
VideoSettingFragment.KEY_REVERSE_LANDSCAPE -> R.id.full_mode_rl
VideoSettingFragment.KEY_UNSPECIFIED -> R.id.full_mode_u
VideoSettingFragment.KEY_AUTO -> R.id.full_mode_auto
else -> R.id.full_mode_sl
}
popupMenu.inflate(R.menu.player_full_mode)
Expand All @@ -223,6 +246,7 @@ class PlayerController(
R.id.full_mode_l -> VideoSettingFragment.KEY_LANDSCAPE
R.id.full_mode_rl -> VideoSettingFragment.KEY_REVERSE_LANDSCAPE
R.id.full_mode_u -> VideoSettingFragment.KEY_UNSPECIFIED
R.id.full_mode_auto -> VideoSettingFragment.KEY_AUTO
else -> VideoSettingFragment.KEY_SENSOR_LANDSCAPE
}
val prefs = PreferenceManager.getDefaultSharedPreferences(activity)
Expand Down Expand Up @@ -267,6 +291,23 @@ class PlayerController(
smallScreen()
}

/**
* 到准备完成后执行
*/
fun postPrepared(id: String, action: Runnable) {
preparedRunQueue.add(Pair(id, action))
}

override fun onPrepared() {
preparedRunQueue.forEach {
val (id, action) = it
if (id == delegate.playerSourceId) {
views.videoPlayer.post(action)
}
}
preparedRunQueue = mutableListOf()
}

override fun onVideoPause() {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.preference.PreferenceManager
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import android.widget.RelativeLayout
import androidx.annotation.OptIn
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.media3.common.MediaItem
import androidx.media3.common.util.UnstableApi
import androidx.media3.datasource.DataSource
Expand All @@ -27,6 +30,7 @@ import com.a10miaomiao.bilimiao.comm.delegate.player.entity.PlayerSourceInfo
import com.a10miaomiao.bilimiao.comm.delegate.player.model.BangumiPlayerSource
import com.a10miaomiao.bilimiao.comm.delegate.player.model.VideoPlayerSource
import com.a10miaomiao.bilimiao.comm.delegate.theme.ThemeDelegate
import com.a10miaomiao.bilimiao.comm.dialogx.showTop
import com.a10miaomiao.bilimiao.comm.entity.player.SubtitleJsonInfo
import com.a10miaomiao.bilimiao.comm.exception.AreaLimitException
import com.a10miaomiao.bilimiao.comm.exception.DabianException
Expand All @@ -35,6 +39,8 @@ import com.a10miaomiao.bilimiao.comm.network.MiaoHttp
import com.a10miaomiao.bilimiao.comm.network.MiaoHttp.Companion.gson
import com.a10miaomiao.bilimiao.comm.proxy.ProxyServerInfo
import com.a10miaomiao.bilimiao.comm.store.UserStore
import com.a10miaomiao.bilimiao.comm.utils.DebugMiao
import com.a10miaomiao.bilimiao.comm.utils.NumberUtil
import com.a10miaomiao.bilimiao.comm.utils.UrlUtil
import com.a10miaomiao.bilimiao.config.config
import com.a10miaomiao.bilimiao.page.setting.VideoSettingFragment
Expand All @@ -46,14 +52,14 @@ import com.a10miaomiao.bilimiao.widget.player.media3.ExoMediaSourceInterceptList
import com.a10miaomiao.bilimiao.widget.player.media3.ExoSourceManager
import com.a10miaomiao.bilimiao.widget.player.media3.Libgav1Media3ExoPlayerManager
import com.a10miaomiao.bilimiao.widget.player.media3.Media3ExoPlayerManager
import com.kongzue.dialogx.dialogs.PopTip
import com.shuyu.gsyvideoplayer.player.PlayerFactory
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.kodein.di.DI
import org.kodein.di.DIAware
import org.kodein.di.instance
import splitties.toast.toast
import java.io.File
import java.net.UnknownHostException

Expand Down Expand Up @@ -107,6 +113,7 @@ class PlayerDelegate2(
playerStore.clearPlayerInfo()
}
}
val playerSourceId get() = playerSource?.id ?: ""

override fun onCreate(savedInstanceState: Bundle?) {
initPlayer()
Expand Down Expand Up @@ -173,7 +180,10 @@ class PlayerDelegate2(
@OptIn(markerClass = [UnstableApi::class])
private fun initPlayer() {
val prefs = PreferenceManager.getDefaultSharedPreferences(activity)
val playerEngine = prefs.getString(VideoSettingFragment.PLAYER_DECODER, VideoSettingFragment.DECODER_DEFAULT)
val playerEngine = prefs.getString(
VideoSettingFragment.PLAYER_DECODER,
VideoSettingFragment.DECODER_DEFAULT
)
if (playerEngine == VideoSettingFragment.DECODER_AV1) {
// AV1
PlayerFactory.setPlayManager(Libgav1Media3ExoPlayerManager::class.java)
Expand Down Expand Up @@ -277,8 +287,11 @@ class PlayerDelegate2(
}

private fun historyReport() {
playerCoroutineScope.launch(Dispatchers.IO) {
playerSource?.historyReport(views.videoPlayer.currentPositionWhenPlaying / 1000)
val progress = views.videoPlayer.currentPositionWhenPlaying / 1000
playerSource?.let {
activity.lifecycleScope.launch(Dispatchers.IO) {
it.historyReport(progress)
}
}
}

Expand All @@ -294,7 +307,7 @@ class PlayerDelegate2(
lastPosition = views.videoPlayer.currentPositionWhenPlaying
speed = newSpeed
views.videoPlayer.setSpeed(speed, true)
toast("已切换到${speed}倍速")
PopTip.show("已切换到${speed}倍速").showTop()
val prefs = PreferenceManager.getDefaultSharedPreferences(activity)
prefs.edit().putFloat("player_speed", newSpeed).apply()
}
Expand All @@ -307,7 +320,7 @@ class PlayerDelegate2(
loadPlayerSource(
isChangedQuality = true
)
toast("正在切换清晰度")
PopTip.show("正在切换清晰度").showTop()
val prefs = PreferenceManager.getDefaultSharedPreferences(activity)
prefs.edit().putInt("player_quality", newQuality).apply()
}
Expand Down Expand Up @@ -343,18 +356,32 @@ class PlayerDelegate2(
if (lastPosition > 0L) {
views.videoPlayer.seekOnStart = lastPosition
lastPosition = 0L
} else {
views.videoPlayer.seekOnStart = 0
} else if (
sourceInfo.lastPlayCid == source.id
&& sourceInfo.lastPlayTime > 0L
) {
views.videoPlayer.seekOnStart = sourceInfo.lastPlayTime
lastPosition = 0L
val lastTimeStr = NumberUtil.converDuration(sourceInfo.lastPlayTime / 1000)
controller.postPrepared(sourceInfo.lastPlayCid) {
PopTip.show("自动恢复:$lastTimeStr", "重新开始")
.showTop()
.showLong()
.setButton { dialog, v ->
views.videoPlayer.startPlayLogic()
false
}
}
}
views.videoPlayer.startPlayLogic()

historyReport()

if (isChangedQuality) {
if (sourceInfo.quality == quality) {
toast("已切换至【${sourceInfo.description}")
PopTip.show("已切换至【${sourceInfo.description}").showTop()
} else {
toast("清晰度切换失败")
PopTip.show("清晰度切换失败").showTop()
}
} else {
views.videoPlayer.subtitleSourceList = withContext(Dispatchers.IO) {
Expand All @@ -377,7 +404,7 @@ class PlayerDelegate2(
withContext(Dispatchers.Main) {
errorMessageBoxController.show("少儿不宜,禁止观看", canRetry = false)
}
} catch (e: AreaLimitException) {
} catch (e: AreaLimitException) {
withContext(Dispatchers.Main) {
(playerSource as? BangumiPlayerSource)?.let {
areaLimitBoxController.show(it)
Expand Down Expand Up @@ -417,11 +444,9 @@ class PlayerDelegate2(
)
}
} catch (e: Throwable) {
// 避免解析信息出错导致崩溃
// showErrorLayout(e.message.toString())
e.printStackTrace()
withContext(Dispatchers.Main) {
toast(e.message.toString())
PopTip.show(e.message.toString()).showTop()
}
}
}
Expand All @@ -435,15 +460,15 @@ class PlayerDelegate2(
val showSubtitle = prefs.getBoolean(VideoSettingFragment.PLAYER_SUBTITLE_SHOW, true)
val showAiSubtitle = prefs.getBoolean(VideoSettingFragment.PLAYER_AI_SUBTITLE_SHOW, false)
if (showSubtitle) {
return list.find { showAiSubtitle || it.ai_status == 0 }
return list.find { showAiSubtitle || it.ai_status == 0 }
}
return null
}

/**
* 记录播放位置
*/
fun reloadPlayer () {
fun reloadPlayer() {
lastPosition = views.videoPlayer.currentPositionWhenPlaying
loadPlayerSource()
}
Expand Down Expand Up @@ -476,14 +501,13 @@ class PlayerDelegate2(
scaffoldApp.showPlayer = true
playerCoroutineScope.onStart()
playerSource = source
// setThumbImageView(source.coverUrl)
setThumbImageView(source.coverUrl)
views.videoPlayer.setSpeed(speed, true)
loadPlayerSource()
// 播放倍速提示
if (speed != 1f) {
toast("注意,当前为${speed}倍速")
PopTip.show("注意,当前为${speed}倍速").showTop()
}

activity.window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

// 播放器是否默认全屏播放
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,35 +41,37 @@ class BangumiPlayerSource(
} ?: BiliApiService.playerAPI.getBangumiUrl(
epid, id, quality, fnval
)
val dash = res.dash
var duration: Long
val url = if (dash != null) {
duration = dash.duration * 1000L
DashSource(res.quality, dash, uposHost).getMDPUrl()
} else {
val durl = if (uposHost.isBlank()) {
res.durl!!
} else {
res.durl!!.map {
it.copy(url = UrlUtil.replaceHost(it.url, uposHost))
}
return PlayerSourceInfo().also {
it.lastPlayCid = res.last_play_cid
it.lastPlayTime = res.last_play_time
it.quality = res.quality
it.acceptList = res.accept_quality.mapIndexed { index, i ->
PlayerSourceInfo.AcceptInfo(i, res.accept_description[index])
}
if (durl.size == 1) {
duration = durl[0].length * 1000L
durl[0].url
val dash = res.dash
if (dash != null) {
it.duration = dash.duration * 1000L
val dashSource = DashSource(res.quality, dash)
val dashVideo = dashSource.getDashVideo()!!
it.height = dashVideo.height
it.width = dashVideo.width
it.url = dashSource.getMDPUrl(dashVideo)
} else {
duration = 0L
"[concatenating]\n" + durl.joinToString("\n") {
duration += it.length * 1000L
it.url
val durl = res.durl!!
if (durl.size == 1) {
it.duration = durl[0].length * 1000L
it.url = durl[0].url
} else {
var duration = 0L
it.url = "[concatenating]\n" + durl.joinToString("\n") { d ->
duration += d.length * 1000L
d.url
}
it.duration = duration
}

}
}
val acceptDescription = res.accept_description
val acceptList = res.accept_quality.mapIndexed { index, i ->
PlayerSourceInfo.AcceptInfo(i, acceptDescription[index])
}
return PlayerSourceInfo(url, res.quality, acceptList, duration)
}

override suspend fun getSubtitles(): List<SubtitleSourceInfo> {
Expand Down
Loading

0 comments on commit 9caa5e5

Please sign in to comment.