Skip to content

Commit

Permalink
Customize subtitle: font color
Browse files Browse the repository at this point in the history
  • Loading branch information
yujincheng08 committed Jul 1, 2021
1 parent c8fd438 commit 8b328d3
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 5 deletions.
27 changes: 26 additions & 1 deletion app/src/main/java/me/iacn/biliroaming/BiliBiliPackage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.os.Bundle
import android.text.style.LineBackgroundSpan
import android.util.Base64
import android.util.SparseArray
import android.view.View
Expand Down Expand Up @@ -202,6 +203,8 @@ class BiliBiliPackage constructor(private val mClassLoader: ClassLoader, mContex
mClassLoader
)
}
val subtitleSpanClass by Weak { mHookInfo["class_subtitle_span"]?.findClassOrNull(mClassLoader) }
val chronosSwitchClass by Weak { mHookInfo["class_chronos_switch"]?.findClassOrNull(mClassLoader) }

val classesList by lazy { mClassLoader.allClassesList() }
private val accessKeyInstance by lazy {
Expand Down Expand Up @@ -448,7 +451,7 @@ class BiliBiliPackage constructor(private val mClassLoader: ClassLoader, mContex
findThemeNameField()
}.checkOrPut("class_section") {
findSectionClass()
}.checkOrPut("class_party_section"){
}.checkOrPut("class_party_section") {
findPartySectionClass()
}.checkOrPut("method_sign_query") {
findSignQueryMethod()
Expand Down Expand Up @@ -509,13 +512,35 @@ class BiliBiliPackage constructor(private val mClassLoader: ClassLoader, mContex
"method_pegasus_feed"
) {
findPegasusFeed()
}.checkOrPut("class_chronos_switch") {
findChronosSwitch()
}.checkOrPut("class_subtitle_span") {
findSubtitleSpan()
}

Log.d(mHookInfo.filterKeys { it != "map_ids" })
Log.d("Check hook info completed: needUpdate = $needUpdate")
return needUpdate
}

private fun findSubtitleSpan() = classesList.filter {
it.startsWith("tv.danmaku.danmaku.subititle") ||
it.startsWith("tv.danmaku.danmaku.subtitle")
}.firstOrNull { c ->
c.findClass(mClassLoader).interfaces.contains(LineBackgroundSpan::class.java)
}

private fun findChronosSwitch(): String? {
val regex = Regex("""^tv\.danmaku\.chronos\.wrapper\.[^.]*$""")
return classesList.filter {
it.matches(regex)
}.firstOrNull { c ->
c.findClass(mClassLoader).declaredFields.count {
it.type == Boolean::class.javaObjectType
} >= 5
}
}

private fun findPegasusFeed(): Array<String?> {
val itemClass =
"com.bilibili.pegasus.api.model.BasicIndexItem".findClassOrNull(mClassLoader)
Expand Down
33 changes: 29 additions & 4 deletions app/src/main/java/me/iacn/biliroaming/SettingDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class SettingDialog(context: Context) : AlertDialog.Builder(context) {
packageName + "_preferences",
Context.MODE_MULTI_PROCESS
)
if (!prefs.getBoolean("hidden", false)) {
if (!prefs.getBoolean("hidden", false)) {
val hiddenGroup = findPreference("hidden_group") as PreferenceCategory
preferenceScreen.removePreference(hiddenGroup)
}
Expand All @@ -76,6 +76,7 @@ class SettingDialog(context: Context) : AlertDialog.Builder(context) {
findPreference("export_video")?.onPreferenceClickListener = this
findPreference("hide_low_play_count_recommend")?.onPreferenceClickListener = this
findPreference("keywords_filter_title_recommend")?.onPreferenceClickListener = this
findPreference("custom_subtitle")?.onPreferenceChangeListener = this
checkCompatibleVersion()
checkUpdate()
}
Expand Down Expand Up @@ -146,7 +147,8 @@ class SettingDialog(context: Context) : AlertDialog.Builder(context) {
val supportDrawer = instance.homeUserCenterClass != null
val supportcustomplaybackspeed = instance.playerCoreServiceV2Class != null
val supportTeenagersMode = instance.teenagersModeDialogActivityClass != null
val suppportPurifyEndpage = "tv.danmaku.biliplayer.context.config.Feature" in instance.classesList
val suppportPurifyEndpage =
"tv.danmaku.biliplayer.context.config.Feature" in instance.classesList
if (!suppportPurifyEndpage)
disablePreference("purify_endpage")
if (!supportcustomplaybackspeed)
Expand Down Expand Up @@ -203,6 +205,24 @@ class SettingDialog(context: Context) : AlertDialog.Builder(context) {
}
}

private fun showCustomSubtitle() {
AlertDialog.Builder(activity).run {
val layout = moduleRes.getLayout(R.layout.custom_subtitle)
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(layout, null)
val fontColor = view.findViewById<EditText>(R.id.font_color)
fontColor.setText(prefs.getInt(fontColor.tag.toString(), 0x7fffffff).toString(16))

setTitle("自定义字幕样式")
setView(view)

setPositiveButton(android.R.string.ok) { _, _ ->
val color = fontColor.text.toString().toInt(16)
prefs.edit().putInt(fontColor.tag.toString(), color).apply()
}
}.show()
}

override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
when (preference.key) {
"custom_splash" -> {
Expand All @@ -228,6 +248,11 @@ class SettingDialog(context: Context) : AlertDialog.Builder(context) {
preference.editor.remove(preference.key).apply()
}
}
"custom_subtitle" -> {
if (newValue as Boolean) {
showCustomSubtitle()
}
}
}
return true
}
Expand Down Expand Up @@ -407,7 +432,7 @@ class SettingDialog(context: Context) : AlertDialog.Builder(context) {
return true
}

private fun oncustomizedanmakuconfigclick(): Boolean {
private fun onCustomizeDanmakuConfigClick(): Boolean {
AlertDialog.Builder(activity).run {
val layout = moduleRes.getLayout(R.layout.cutomize_danmaku_config_dialog)
val inflater = LayoutInflater.from(context)
Expand Down Expand Up @@ -550,7 +575,7 @@ class SettingDialog(context: Context) : AlertDialog.Builder(context) {
"custom_server" -> onCustomServerClick()
"test_upos" -> onTestUposClick()
"customize_bottom_bar" -> onCustomizeBottomBarClick()
"customize_danmaku_config" -> oncustomizedanmakuconfigclick()
"customize_danmaku_config" -> onCustomizeDanmakuConfigClick()
"pref_export" -> onPrefExportClick()
"pref_import" -> onPrefImportClick()
"export_video" -> onExportVideoClick()
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/me/iacn/biliroaming/XposedInit.kt
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class XposedInit : IXposedHookLoadPackage, IXposedHookZygoteInit {
startHook(MusicNotificationHook(lpparam.classLoader))
startHook(DrawerHook(lpparam.classLoader))
startHook(CoverHook(lpparam.classLoader))
startHook(SubtitleHook(lpparam.classLoader))
}
lpparam.processName.endsWith(":web") -> {
BiliBiliPackage(lpparam.classLoader, param.args[0] as Context)
Expand Down
65 changes: 65 additions & 0 deletions app/src/main/java/me/iacn/biliroaming/hook/SubtitleHook.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package me.iacn.biliroaming.hook

import android.graphics.Rect
import android.text.SpannableString
import android.text.style.ForegroundColorSpan
import android.text.style.LineBackgroundSpan
import me.iacn.biliroaming.BiliBiliPackage.Companion.instance
import me.iacn.biliroaming.utils.*
import kotlin.math.roundToInt


class SubtitleHook(classLoader: ClassLoader) : BaseHook(classLoader) {
override fun startHook() {
if (!sPrefs.getBoolean("custom_subtitle", false)) return
Log.d("startHook: Subtitle")

instance.chronosSwitchClass?.hookAfterConstructor { param ->
param.thisObject.javaClass.declaredFields.forEach {
if (it.type == Boolean::class.javaObjectType) {
param.thisObject.setObjectField(it.name, false)
}
}
}

val rect = Rect()
val margin = 3
val backgroundColor = 0x7f000000
val backgroundSpan =
LineBackgroundSpan { canvas, paint, left, right, top, _, bottom, text, start, end, _ ->
val width = paint.measureText(text, start, end).roundToInt()
val textLeft = (right - left - width) / 2
val color = paint.color
rect.set(textLeft - margin, top, textLeft + width + margin, bottom)
paint.color = backgroundColor
canvas.drawRect(rect, paint)
paint.color = color
}

android.text.SpannableString::class.java.hookBeforeMethod(
"setSpan",
Object::class.java,
Int::class.java,
Int::class.java,
Int::class.java
) { param ->
if (instance.subtitleSpanClass?.isInstance(param.args[0]) != true) return@hookBeforeMethod
val (start, end, flags) = listOf(
param.args[1] as Int,
param.args[2] as Int,
param.args[3] as Int
)
(param.thisObject as SpannableString).run {
setSpan(
ForegroundColorSpan(sPrefs.getInt("subtitle_font_color", 0x7fffffff)),
start,
end,
flags
)
param.result = null
}
}


}
}
32 changes: 32 additions & 0 deletions app/src/main/res/layout/custom_subtitle.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:rowCount="4"
android:columnCount="2"
android:orientation="horizontal"
android:paddingStart="25dp"
android:paddingEnd="20dp">


<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:text="字体颜色"
android:singleLine="true"
tools:ignore="HardcodedText" />

<EditText
android:id="@+id/font_color"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="4"
android:hint="00000000"
android:tag="subtitle_font_color"
android:inputType="number"
android:autofillHints="no"
tools:ignore="HardcodedText" />
</GridLayout>
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,6 @@
<string name="keywords_filter_title_recommend_title">关键词过滤首页推送</string>
<string name="add_channel_title">添加频道按钮</string>
<string name="add_channel_summary">在底栏添加频道按钮(请在自定义底栏中把发布关掉)</string>
<string name="custom_subtitle_title">自定义字幕样式</string>
<string name="custom_subtitle_summary">开启后能自定义CC字幕样式,但透明度跟随弹幕透明度</string>
</resources>
4 changes: 4 additions & 0 deletions app/src/main/res/xml/prefs_setting.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@
android:key="drawer"
android:summary="@string/drawer_summary"
android:title="@string/drawer_title" />
<SwitchPreference
android:key="custom_subtitle"
android:summary="@string/custom_subtitle_summary"
android:title="@string/custom_subtitle_title" />
</PreferenceCategory>

<PreferenceCategory android:title="@string/miscellaneous_category">
Expand Down

0 comments on commit 8b328d3

Please sign in to comment.