Skip to content

Commit 6e133e5

Browse files
committed
启用音频软解
为 Media3 增加 Ffmpeg 音频解码器,解决部分设备播放部分音频时 MediaCodec 硬解出现错误的问题 fixed #166
1 parent 403c6f7 commit 6e133e5

File tree

9 files changed

+61
-5
lines changed

9 files changed

+61
-5
lines changed

app/src/main/kotlin/dev/aaa1115910/bv/activities/video/VideoPlayerV3Activity.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ class VideoPlayerV3Activity : ComponentActivity() {
9595
referer = when (Prefs.apiType) {
9696
ApiType.Web -> getString(R.string.video_player_referer)
9797
ApiType.App -> null
98-
}
98+
},
99+
enableFfmpegAudioRenderer = Prefs.enableFfmpegAudioRenderer
99100
)
100101
val videoPlayer = when (Prefs.playerType) {
101102
PlayerType.Media3 -> ExoPlayerFactory().create(this, options)

app/src/main/kotlin/dev/aaa1115910/bv/screen/settings/content/OtherSetting.kt

+12
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ fun OtherSetting(
4040
var showFps by remember { mutableStateOf(Prefs.showFps) }
4141
var useOldPlayer by remember { mutableStateOf(Prefs.useOldPlayer) }
4242
var updateAlpha by remember { mutableStateOf(Prefs.updateAlpha) }
43+
var enableFfmpegAudioRenderer by remember { mutableStateOf(Prefs.enableFfmpegAudioRenderer) }
4344

4445
Column(
4546
modifier = modifier.fillMaxSize(),
@@ -129,6 +130,17 @@ fun OtherSetting(
129130
)
130131
}
131132
}
133+
item {
134+
SettingSwitchListItem(
135+
title = stringResource(R.string.settings_other_ffmpeg_audio_renderer_title),
136+
supportText = stringResource(R.string.settings_other_ffmpeg_audio_renderer_text),
137+
checked = enableFfmpegAudioRenderer,
138+
onCheckedChange = {
139+
enableFfmpegAudioRenderer = it
140+
Prefs.enableFfmpegAudioRenderer = it
141+
}
142+
)
143+
}
132144
}
133145
}
134146

app/src/main/kotlin/dev/aaa1115910/bv/util/Prefs.kt

+13
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,17 @@ object Prefs {
284284
dsm.getPreferenceFlow(PrefKeys.prefDefaultDanmakuMaskRequest).first()
285285
}
286286
set(value) = runBlocking { dsm.editPreference(PrefKeys.prefDefaultDanmakuMask, value) }
287+
288+
var enableFfmpegAudioRenderer: Boolean
289+
get() = runBlocking {
290+
dsm.getPreferenceFlow(PrefKeys.prefEnableFfmpegEndererRequest).first()
291+
}
292+
set(value) = runBlocking {
293+
dsm.editPreference(
294+
PrefKeys.prefEnableFfmpegAudioRenderer,
295+
value
296+
)
297+
}
287298
}
288299

289300
private object PrefKeys {
@@ -327,6 +338,7 @@ private object PrefKeys {
327338
val prefShowedRemoteControllerPanelDemoKey = booleanPreferencesKey("showed_rcpd")
328339
val prefPreferOfficialCdn = booleanPreferencesKey("prefer_official_cdn")
329340
val prefDefaultDanmakuMask = booleanPreferencesKey("prefer_enable_webmark")
341+
val prefEnableFfmpegAudioRenderer = booleanPreferencesKey("enable_ffmpeg_audio_renderer")
330342

331343
val prefIsLoginRequest = PreferenceRequest(prefIsLoginKey, false)
332344
val prefUidRequest = PreferenceRequest(prefUidKey, 0)
@@ -378,4 +390,5 @@ private object PrefKeys {
378390
PreferenceRequest(prefShowedRemoteControllerPanelDemoKey, false)
379391
val prefPreferOfficialCdnRequest = PreferenceRequest(prefPreferOfficialCdn, false)
380392
val prefDefaultDanmakuMaskRequest = PreferenceRequest(prefDefaultDanmakuMask, false)
393+
val prefEnableFfmpegEndererRequest = PreferenceRequest(prefEnableFfmpegAudioRenderer, false)
381394
}

app/src/main/res/values/strings.xml

+2
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@
239239
<string name="settings_other_alpha_title">Alpha 版更新</string>
240240
<string name="settings_other_cookies_text">该功能不适合使用遥控器操作</string>
241241
<string name="settings_other_cookies_title">Cookies 导入/导出</string>
242+
<string name="settings_other_ffmpeg_audio_renderer_text">尝试使用 FFmpeg 播放硬解不兼容的音频</string>
243+
<string name="settings_other_ffmpeg_audio_renderer_title">启用音频软解</string>
242244
<string name="settings_other_firebase_text">这将帮助开发者更快地发现与解决大部分问题</string>
243245
<string name="settings_other_firebase_title">发送错误日志</string>
244246
<string name="settings_other_fps_text">在屏幕左上角显示 FPS,这需要重启 App</string>

bv-player/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ dependencies {
7373
implementation(androidx.media3.exoplayer)
7474
implementation(androidx.media3.ui)
7575
implementation(libs.material)
76+
implementation(project(":libs:ffmpegDecoder"))
7677
testImplementation(libs.kotlin.test)
7778
androidTestImplementation(androidx.compose.ui.test.junit4)
7879
debugImplementation(androidx.compose.ui.test.manifest)

bv-player/src/main/kotlin/dev/aaa1115910/bv/player/VideoPlayerOptions.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ package dev.aaa1115910.bv.player
22

33
data class VideoPlayerOptions(
44
val userAgent: String? = null,
5-
val referer: String? = null
5+
val referer: String? = null,
6+
val enableFfmpegAudioRenderer: Boolean = false
67
)

bv-player/src/main/kotlin/dev/aaa1115910/bv/player/impl/exo/ExoMediaPlayer.kt

+27-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ package dev.aaa1115910.bv.player.impl.exo
22

33
import android.content.Context
44
import androidx.annotation.OptIn
5+
import androidx.media3.common.C
56
import androidx.media3.common.MediaItem
67
import androidx.media3.common.PlaybackException
78
import androidx.media3.common.Player
89
import androidx.media3.common.util.UnstableApi
910
import androidx.media3.datasource.okhttp.OkHttpDataSource
11+
import androidx.media3.exoplayer.DefaultRenderersFactory
1012
import androidx.media3.exoplayer.ExoPlayer
13+
import androidx.media3.exoplayer.Renderer
1114
import androidx.media3.exoplayer.source.MediaSource
1215
import androidx.media3.exoplayer.source.MergingMediaSource
1316
import androidx.media3.exoplayer.source.ProgressiveMediaSource
@@ -37,8 +40,17 @@ class ExoMediaPlayer(
3740

3841
@OptIn(UnstableApi::class)
3942
override fun initPlayer() {
43+
val renderersFactory = DefaultRenderersFactory(context).apply {
44+
setExtensionRendererMode(
45+
when (options.enableFfmpegAudioRenderer) {
46+
true -> DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON
47+
false -> DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF
48+
}
49+
)
50+
}
4051
mPlayer = ExoPlayer
4152
.Builder(context)
53+
.setRenderersFactory(renderersFactory)
4254
.setSeekForwardIncrementMs(1000 * 10)
4355
.setSeekBackIncrementMs(1000 * 5)
4456
.build()
@@ -156,9 +168,22 @@ class ExoMediaPlayer(
156168
resolution: ${mPlayer?.videoSize?.width} x ${mPlayer?.videoSize?.height}
157169
audio: ${mPlayer?.audioFormat?.bitrate ?: 0} kbps
158170
video codec: ${mPlayer?.videoFormat?.sampleMimeType ?: "null"}
159-
audio codec: ${mPlayer?.audioFormat?.sampleMimeType ?: "null"}
160-
""".trimIndent()
171+
audio codec: ${mPlayer?.audioFormat?.sampleMimeType ?: "null"} (${getAudioRendererName()})
172+
""".trimIndent().also {
173+
println(mPlayer?.audioFormat)
174+
}
175+
}
176+
177+
private fun getAudioRendererName(): String {
178+
val rendererCount = mPlayer?.rendererCount ?: return "UnknownRenderer"
179+
for (i in 0 until rendererCount) {
180+
val renderer = mPlayer!!.getRenderer(i)
181+
if (renderer.trackType == C.TRACK_TYPE_AUDIO && renderer.state == Renderer.STATE_STARTED) {
182+
return renderer.name
183+
}
161184
}
185+
return "UnknownRenderer"
186+
}
162187

163188
override val videoWidth: Int
164189
get() = mPlayer?.videoSize?.width ?: 0

settings.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ include(":bili-api")
3232
include(":bili-subtitle")
3333
include(":bv-player")
3434
include(":libs:av1Decoder")
35+
include(":libs:ffmpegDecoder")
3536
include(":libs:libVLC")
3637
include(":bili-api-grpc")

0 commit comments

Comments
 (0)