BiliRoamingX项目中的播放速度覆盖功能失效问题分析

BiliRoamingX项目中的播放速度覆盖功能失效问题分析

【免费下载链接】BiliRoamingX-integrations BiliRoamingX integrations powered by revanced. 【免费下载链接】BiliRoamingX-integrations 项目地址: https://gitcode.com/gh_mirrors/bi/BiliRoamingX-integrations

问题背景

BiliRoamingX作为基于ReVanced实现的B站Android客户端增强模块,提供了丰富的自定义功能,其中播放速度覆盖功能允许用户自定义播放器速度选项列表。然而,在实际使用中,部分用户反馈该功能在某些场景下会出现失效问题。

功能架构解析

核心组件结构

mermaid

关键代码实现

设置存储层
// Settings.kt
@JvmField val OverridePlaybackSpeed = StringSetting(key = "playback_speed_override")
业务逻辑层
// PlaybackSpeedPatch.kt
private val newSpeedArray: FloatArray
    get() = if (cacheOverrideSpeed == Settings.OverridePlaybackSpeed()) {
        cacheSpeedArray
    } else {
        cacheOverrideSpeed = Settings.OverridePlaybackSpeed()
        cacheSpeedArray = cacheOverrideSpeed.let { v ->
            if (v.isEmpty()) floatArrayOf()
            else v.split(' ').map { it.toFloat() }.toFloatArray()
        }
        cacheReverseSpeedArray = cacheSpeedArray.reversedArray()
        cacheSpeedArray
    }
补丁注入层
// OverridePlaybackSpeedPatch.kt
m.addInstructions(
    insertIndex, """
    invoke-static {v$register}, Lapp/revanced/bilibili/patches/PlaybackSpeedPatch;->getOverrideSpeedArray([F)[F
    move-result-object v$register
""".trimIndent()
)

失效问题深度分析

1. 缓存机制导致的同步问题

问题现象:修改设置后需要重启应用才能生效

根本原因:缓存机制设计缺陷

private var cacheOverrideSpeed = ""
private var cacheSpeedArray = floatArrayOf()

// 缓存检查逻辑
if (cacheOverrideSpeed == Settings.OverridePlaybackSpeed()) {
    cacheSpeedArray  // 返回缓存值
} else {
    // 重新计算并更新缓存
}

问题分析

  • 缓存字符串比较基于引用而非内容
  • 设置更新后缓存未及时失效
  • 需要应用重启才能重新计算

2. 多播放器场景适配问题

支持的播放器类型
播放器类型支持状态适配方式
主播放器✅ 完全支持SpeedFunctionWidgetFingerprint
Story播放器✅ 完全支持StoryMenuFingerprint
播客播放器⚠️ 部分支持PodcastSpeedSeekBar反射
音乐播放器⚠️ 条件支持MusicPlayerPanelFingerprint
统一播放器✅ 新版支持UnitePlayerSetSpeedMenuFingerprint

3. 版本兼容性问题

B站客户端版本碎片化严重

mermaid

兼容性挑战

  • 新版统一播放器接口变化
  • 旧版指纹匹配失效
  • 不同版本类名和方法签名差异

4. 设置格式验证问题

有效设置格式示例

1.0 1.25 1.5 2.0  // 空格分隔的浮点数

常见错误格式

1.0,1.25,1.5,2.0  // 使用逗号分隔
1.0 1.25 abc 2.0  // 包含非数字字符
(空字符串)        // 未设置任何值

解决方案与优化建议

1. 缓存机制优化

改进方案

// 添加设置变更监听
Settings.OverridePlaybackSpeed.addOnChangeListener { newValue ->
    cacheOverrideSpeed = ""
    cacheSpeedArray = floatArrayOf()
    cacheReverseSpeedArray = floatArrayOf()
}

// 修改缓存检查逻辑
private val newSpeedArray: FloatArray
    get() {
        val currentSetting = Settings.OverridePlaybackSpeed()
        if (cacheOverrideSpeed != currentSetting) {
            cacheOverrideSpeed = currentSetting
            cacheSpeedArray = if (currentSetting.isEmpty()) floatArrayOf()
                else currentSetting.split(' ').mapNotNull { it.toFloatOrNull() }.toFloatArray()
            cacheReverseSpeedArray = cacheSpeedArray.reversedArray()
        }
        return cacheSpeedArray
    }

2. 设置格式验证增强

fun validateSpeedSettings(input: String): Boolean {
    if (input.isEmpty()) return true
    return input.split(' ').all { part ->
        part.toFloatOrNull()?.let { it > 0 && it <= 10 } ?: false
    }
}

// 添加设置提示
fun getSpeedSettingsHint(): String {
    return "请输入空格分隔的播放速度值(如:0.5 1.0 1.25 1.5 2.0)\n" +
           "支持范围:0.25 - 10.0"
}

3. 多版本兼容性处理

版本检测与适配策略

object VersionCompat {
    fun isUnitePlayerSupported(): Boolean {
        // 检测7.80.0+版本特征
        return try {
            Class.forName("com.bilibili.lib.unite.player.XXX")
            true
        } catch (e: ClassNotFoundException) {
            false
        }
    }
    
    fun getApplicableFingerprints(): Set<Fingerprint> {
        val fingerprints = mutableSetOf<Fingerprint>()
        if (isUnitePlayerSupported()) {
            fingerprints.add(UnitePlayerSetSpeedMenuFingerprint)
        }
        // 添加其他版本特定的指纹
        fingerprints.addAll(setOf(
            SpeedFunctionWidgetFingerprint,
            StoryMenuFingerprint,
            PlaybackSpeedSettingFingerprint
        ))
        return fingerprints
    }
}

4. 错误处理与日志记录

@Keep
@JvmStatic
fun getOverrideSpeedArray(original: FloatArray): FloatArray {
    return try {
        newSpeedArray.let { if (it.isNotEmpty()) it else original }
    } catch (e: Exception) {
        Logger.e("OverridePlaybackSpeed", "Failed to parse speed array: ${e.message}")
        original // 降级到原始数组
    }
}

// 添加调试日志
fun debugLog(message: String) {
    if (Settings.Debug()) {
        Logger.d("PlaybackSpeed", message)
    }
}

测试验证方案

功能测试矩阵

测试场景预期结果验证方法
空设置使用默认速度数组界面显示默认选项
有效设置正确显示自定义速度界面更新验证
无效设置降级到默认数组错误日志记录
设置变更实时生效无需重启动态测试验证
多版本客户端功能正常可用版本兼容性测试

性能优化建议

  1. 懒加载优化:仅在需要时计算速度数组
  2. 内存管理:合理控制缓存生命周期
  3. 线程安全:添加适当的同步机制
  4. 资源释放:及时清理不再使用的资源

总结

BiliRoamingX的播放速度覆盖功能失效问题主要源于缓存同步机制、版本兼容性、设置验证等多方面因素。通过优化缓存策略、增强设置验证、完善版本适配和加强错误处理,可以显著提升功能的稳定性和用户体验。

关键改进点

  • ✅ 实时缓存失效机制
  • ✅ 严格的设置格式验证
  • ✅ 多版本客户端兼容适配
  • ✅ 完善的错误处理和日志记录
  • ✅ 性能优化和资源管理

这些改进措施将确保播放速度覆盖功能在各种使用场景下都能稳定可靠地工作,为用户提供更好的自定义体验。

【免费下载链接】BiliRoamingX-integrations BiliRoamingX integrations powered by revanced. 【免费下载链接】BiliRoamingX-integrations 项目地址: https://gitcode.com/gh_mirrors/bi/BiliRoamingX-integrations

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值