Skip to content

Commit

Permalink
[新增] ExoPlayer 内核并设置为默认内核,该内核不会造成快进回退的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
YenalyLiew committed Apr 22, 2024
1 parent 51b0ad0 commit 3db1537
Show file tree
Hide file tree
Showing 20 changed files with 420 additions and 58 deletions.
16 changes: 16 additions & 0 deletions README_TECH.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Han1meViewer 技术相关

> 抄是程序员进步的阶梯。
## 概括

本软件使用 MVVM 架构,Material 3 视觉风格,Jetpack 不用问肯定用,但未使用 Compose(有一说一不用 Compose
Expand Down Expand Up @@ -154,6 +156,20 @@ override fun onBindViewHolder(

### CI 更新渠道

#### 你可以学到

#### 关键文件

#### 解释

当你的软件拓展性比较高,但受限于题材内容或者单纯懒,不方便自建服务器去读取这些拓展文件。但你又希望能让用户通过其他渠道实时的获取到更新(比如好心人上传了拓展文件,我合并到主分支之后,几分钟后用户就可以获得更新,而不用我自己做包),但又不是所有人需要这些拓展功能(要是人家不愿用你那功能,又一会一个 Release,用户也会烦;你自己一会发一个包你也会烦)。所以能不能给用户提供两种渠道?一个是稳定更新渠道,自己发版本;另一个是开发版,GitHub 自动构建,保证最新功能(最新拓展功能立即集成)但不保证稳定性。

答案是肯定的。其实我之前也不知道怎么做,但是 @NekoOuO 给我发了 [Foolbar/EhViewer](https://github.com/FooIbar/EhViewer/) 的做法,我想都没想就抄过来了。但没人详细教怎么做,我今天就来讲讲。

**先去看** GitHub CI 基础用法。

谷歌、掘金上全是教程。你先去查一查用法然后配置一下,刚开始的要求不多,你上传 commit 之后,GitHub CI 开始工作并成功 Build,就算入门了,先不用管 Build 之后干什么或者别的。如果你操作非常顺利,再看以下步骤。

待更...

### 共享关键H帧
Expand Down
3 changes: 3 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ dependencies {
// video

implementation(libs.jiaozi.video.player)
implementation(libs.media3.exoplayer)

// view

Expand All @@ -149,6 +150,8 @@ dependencies {

androidTestImplementation(libs.test.junit)
androidTestImplementation(libs.test.espresso.core)

debugImplementation(libs.leak.canary)
}

/**
Expand Down
9 changes: 8 additions & 1 deletion app/src/main/java/com/yenaly/han1meviewer/Preferences.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import com.yenaly.han1meviewer.ui.fragment.settings.HKeyframeSettingsFragment
import com.yenaly.han1meviewer.ui.fragment.settings.HomeSettingsFragment
import com.yenaly.han1meviewer.ui.fragment.settings.NetworkSettingsFragment
import com.yenaly.han1meviewer.ui.fragment.settings.PlayerSettingsFragment
import com.yenaly.han1meviewer.ui.view.HJzvdStd
import com.yenaly.han1meviewer.ui.view.video.HJzvdStd
import com.yenaly.han1meviewer.ui.view.video.HMediaKernel
import com.yenaly.han1meviewer.util.CookieString
import com.yenaly.yenaly_libs.utils.applicationContext
import com.yenaly.yenaly_libs.utils.getSpValue
Expand Down Expand Up @@ -64,6 +65,12 @@ object Preferences {

// 設定 相關

val switchPlayerKernel: String
get() = preferenceSp.getString(
PlayerSettingsFragment.SWITCH_PLAYER_KERNEL,
HMediaKernel.Type.ExoPlayer.name
) ?: HMediaKernel.Type.ExoPlayer.name

val showBottomProgress: Boolean
get() = preferenceSp.getBoolean(
PlayerSettingsFragment.SHOW_BOTTOM_PROGRESS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import cn.jzvd.JZDataSource
import cn.jzvd.Jzvd
import coil.load
import com.yenaly.han1meviewer.COMMENT_TYPE
import com.yenaly.han1meviewer.Preferences
import com.yenaly.han1meviewer.R
import com.yenaly.han1meviewer.VIDEO_CODE
import com.yenaly.han1meviewer.VIDEO_COMMENT_PREFIX
Expand All @@ -24,6 +25,7 @@ import com.yenaly.han1meviewer.logic.exception.ParseException
import com.yenaly.han1meviewer.logic.state.VideoLoadingState
import com.yenaly.han1meviewer.ui.fragment.video.CommentFragment
import com.yenaly.han1meviewer.ui.fragment.video.VideoIntroductionFragment
import com.yenaly.han1meviewer.ui.view.video.HMediaKernel
import com.yenaly.han1meviewer.ui.viewmodel.CommentViewModel
import com.yenaly.han1meviewer.ui.viewmodel.VideoViewModel
import com.yenaly.han1meviewer.util.showAlertDialog
Expand All @@ -50,6 +52,8 @@ class VideoActivity : YenalyActivity<ActivityVideoBinding, VideoViewModel>(),

private val commentViewModel by viewModels<CommentViewModel>()

private val kernel = HMediaKernel.Type.fromString(Preferences.switchPlayerKernel)

private val videoCode by intentExtra<String>(VIDEO_CODE)
private var videoTitle: String? = null
private var videoCodeByWebsite: String? = null
Expand Down Expand Up @@ -107,7 +111,7 @@ class VideoActivity : YenalyActivity<ActivityVideoBinding, VideoViewModel>(),
} else {
binding.videoPlayer.setUp(
JZDataSource(state.info.videoUrls, state.info.title),
Jzvd.SCREEN_NORMAL
Jzvd.SCREEN_NORMAL, kernel
)
}
binding.videoPlayer.posterImageView.load(state.info.coverUrl) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import android.view.ViewGroup
import android.widget.TextView
import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.yenaly.han1meviewer.ui.view.HJzvdStd
import com.yenaly.han1meviewer.ui.view.video.HJzvdStd

/**
* @project Han1meViewer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import androidx.preference.SwitchPreferenceCompat
import com.yenaly.han1meviewer.R
import com.yenaly.han1meviewer.ui.activity.SettingsActivity
import com.yenaly.han1meviewer.ui.fragment.IToolbarFragment
import com.yenaly.han1meviewer.ui.view.HJzvdStd
import com.yenaly.han1meviewer.ui.view.video.HJzvdStd
import com.yenaly.yenaly_libs.base.settings.YenalySettingsFragment

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import com.yenaly.han1meviewer.logic.state.WebsiteState
import com.yenaly.han1meviewer.ui.activity.AboutActivity
import com.yenaly.han1meviewer.ui.activity.SettingsActivity
import com.yenaly.han1meviewer.ui.fragment.IToolbarFragment
import com.yenaly.han1meviewer.ui.view.MaterialDialogPreference
import com.yenaly.han1meviewer.ui.view.pref.MaterialDialogPreference
import com.yenaly.han1meviewer.ui.viewmodel.AppViewModel
import com.yenaly.han1meviewer.util.hanimeVideoLocalFolder
import com.yenaly.han1meviewer.util.showAlertDialog
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import com.yenaly.han1meviewer.logic.network.HanimeNetwork
import com.yenaly.han1meviewer.logout
import com.yenaly.han1meviewer.ui.activity.SettingsActivity
import com.yenaly.han1meviewer.ui.fragment.IToolbarFragment
import com.yenaly.han1meviewer.ui.view.MaterialDialogPreference
import com.yenaly.han1meviewer.ui.view.pref.MaterialDialogPreference
import com.yenaly.han1meviewer.util.showAlertDialog
import com.yenaly.yenaly_libs.ActivitiesManager
import com.yenaly.yenaly_libs.base.settings.YenalySettingsFragment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import androidx.preference.SwitchPreferenceCompat
import com.yenaly.han1meviewer.R
import com.yenaly.han1meviewer.ui.activity.SettingsActivity
import com.yenaly.han1meviewer.ui.fragment.IToolbarFragment
import com.yenaly.han1meviewer.ui.view.HJzvdStd
import com.yenaly.han1meviewer.ui.view.MaterialDialogPreference
import com.yenaly.han1meviewer.ui.view.pref.MaterialDialogPreference
import com.yenaly.han1meviewer.ui.view.video.HJzvdStd
import com.yenaly.han1meviewer.ui.view.video.HMediaKernel
import com.yenaly.yenaly_libs.base.settings.YenalySettingsFragment

/**
Expand All @@ -20,12 +21,15 @@ class PlayerSettingsFragment : YenalySettingsFragment(R.xml.settings_player),
IToolbarFragment<SettingsActivity> {

companion object {
const val SWITCH_PLAYER_KERNEL = "switch_player_kernel"
const val SHOW_BOTTOM_PROGRESS = "show_bottom_progress"
const val PLAYER_SPEED = "player_speed"
const val SLIDE_SENSITIVITY = "slide_sensitivity"
const val LONG_PRESS_SPEED_TIMES = "long_press_speed_times"
}

private val switchPlayerKernel
by safePreference<MaterialDialogPreference>(SWITCH_PLAYER_KERNEL)
private val showBottomProgressPref
by safePreference<SwitchPreferenceCompat>(SHOW_BOTTOM_PROGRESS)
private val playerSpeed
Expand All @@ -41,6 +45,12 @@ class PlayerSettingsFragment : YenalySettingsFragment(R.xml.settings_player),
}

override fun onPreferencesCreated(savedInstanceState: Bundle?) {
switchPlayerKernel.apply {
val kernelNames = HMediaKernel.Type.entries.map { it.name }.toTypedArray()
entries = kernelNames
entryValues = kernelNames
if (value == null) setValueIndex(HMediaKernel.Type.ExoPlayer.ordinal)
}
playerSpeed.apply {
entries = HJzvdStd.speedStringArray
entryValues = Array(HJzvdStd.speedArray.size) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.yenaly.han1meviewer.ui.view
package com.yenaly.han1meviewer.ui.view.pref

import android.content.Context
import android.util.AttributeSet
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package com.yenaly.han1meviewer.ui.view
package com.yenaly.han1meviewer.ui.view.video

import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ActivityInfo
import android.graphics.Typeface
import android.media.AudioManager
import android.media.MediaPlayer
import android.media.PlaybackParams
import android.provider.Settings
import android.provider.Settings.SettingNotFoundException
import android.util.AttributeSet
Expand All @@ -30,9 +27,7 @@ import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import cn.jzvd.JZDataSource
import cn.jzvd.JZMediaSystem
import cn.jzvd.JZUtils
import cn.jzvd.Jzvd
import cn.jzvd.JzvdStd
import com.itxca.spannablex.spannable
import com.yenaly.han1meviewer.Preferences
Expand All @@ -46,6 +41,7 @@ import com.yenaly.han1meviewer.util.setStateViewLayout
import com.yenaly.han1meviewer.util.showAlertDialog
import com.yenaly.yenaly_libs.utils.OrientationManager
import com.yenaly.yenaly_libs.utils.activity
import com.yenaly.yenaly_libs.utils.appScreenWidth
import com.yenaly.yenaly_libs.utils.unsafeLazy
import com.yenaly.yenaly_libs.utils.view.removeItself
import java.util.Timer
Expand Down Expand Up @@ -253,6 +249,7 @@ class HJzvdStd @JvmOverloads constructor(

override fun init(context: Context?) {
super.init(context)
SAVE_PROGRESS = false
tvSpeed = findViewById(R.id.tv_speed)
tvKeyframe = findViewById(R.id.tv_keyframe)
tvTimer = findViewById(R.id.tv_timer)
Expand All @@ -265,7 +262,15 @@ class HJzvdStd @JvmOverloads constructor(
}

override fun setUp(jzDataSource: JZDataSource?, screen: Int) {
super.setUp(jzDataSource, screen, HJZMediaSystem::class.java)
super.setUp(jzDataSource, screen, ExoMediaKernel::class.java)
}

fun setUp(jzDataSource: JZDataSource?, screen: Int, kernel: HMediaKernel.Type) {
setUp(jzDataSource, screen, kernel.clazz)
}

override fun setUp(jzDataSource: JZDataSource?, screen: Int, clazz: Class<*>) {
super.setUp(jzDataSource, screen, clazz)
Log.d("CustomJzvdStd-Settings", buildString {
append("showBottomProgress: ")
appendLine(showBottomProgress)
Expand Down Expand Up @@ -404,7 +409,7 @@ class HJzvdStd @JvmOverloads constructor(
}
} else {
//如果y轴滑动距离超过设置的处理范围,那么进行滑动事件处理
if (mDownX < mScreenHeight * 0.5f) { //左侧改变亮度
if (mDownX < appScreenWidth * 0.5f) { //左侧改变亮度
mChangeBrightness = true
val lp = JZUtils.getWindow(context).attributes
if (lp.screenBrightness < 0) {
Expand Down Expand Up @@ -637,36 +642,4 @@ class HJzvdStd @JvmOverloads constructor(
else -> throw IllegalStateException("Invalid sensitivity value: $this")
}
}
}

class HJZMediaSystem(jzvd: Jzvd) : JZMediaSystem(jzvd) {

// #issue-26: 有的手機長按快進會報錯,合理懷疑是不是因爲沒有加 post
// #issue-28: 有的平板长按快进也会报错,结果是 IllegalArgumentException,很奇怪,两次 try-catch 处理试试。
override fun setSpeed(speed: Float) {
mMediaHandler.post {
try {
val pp = mediaPlayer.playbackParams
pp.speed = speed.absoluteValue
mediaPlayer.playbackParams = pp
} catch (e: IllegalArgumentException) {
try {
val opp = PlaybackParams().setSpeed(speed.absoluteValue)
mediaPlayer.playbackParams = opp
} catch (e: IllegalArgumentException) {
e.printStackTrace()
}
}
}
}

override fun onVideoSizeChanged(mediaPlayer: MediaPlayer?, width: Int, height: Int) {
super.onVideoSizeChanged(mediaPlayer, width, height)
val ratio = width.toFloat() / height // > 1 橫屏, < 1 竖屏
if (ratio > 1) {
Jzvd.FULLSCREEN_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
} else {
Jzvd.FULLSCREEN_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
}
}
Loading

0 comments on commit 3db1537

Please sign in to comment.