mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Option to transcode surround sound audio to AC3
This commit is contained in:
parent
55b148971e
commit
eecdea92e0
7 changed files with 97 additions and 6 deletions
|
|
@ -52,7 +52,10 @@ sealed interface AppPreference<Pref, T> {
|
||||||
value: T?,
|
value: T?,
|
||||||
): String? = null
|
): String? = null
|
||||||
|
|
||||||
fun validate(value: T): PreferenceValidation = PreferenceValidation.Valid
|
fun validate(
|
||||||
|
prefs: Pref,
|
||||||
|
value: T,
|
||||||
|
): PreferenceValidation = PreferenceValidation.Valid
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val SkipForward =
|
val SkipForward =
|
||||||
|
|
@ -414,18 +417,49 @@ sealed interface AppPreference<Pref, T> {
|
||||||
defaultValue = true,
|
defaultValue = true,
|
||||||
getter = { it.playbackPreferences.overrides.ac3Supported },
|
getter = { it.playbackPreferences.overrides.ac3Supported },
|
||||||
setter = { prefs, value ->
|
setter = { prefs, value ->
|
||||||
prefs.updatePlaybackOverrides { ac3Supported = value }
|
prefs.updatePlaybackOverrides {
|
||||||
|
ac3Supported = value
|
||||||
|
if (!value) preferAc3Surround = false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
summaryOn = R.string.enabled,
|
summaryOn = R.string.enabled,
|
||||||
summaryOff = R.string.disabled,
|
summaryOff = R.string.disabled,
|
||||||
)
|
)
|
||||||
|
val PreferAc3ForSurround =
|
||||||
|
AppSwitchPreference<AppPreferences>(
|
||||||
|
title = R.string.prefer_ac3_for_surround,
|
||||||
|
defaultValue = true,
|
||||||
|
getter = { it.playbackPreferences.overrides.preferAc3Surround },
|
||||||
|
setter = { prefs, value ->
|
||||||
|
prefs.updatePlaybackOverrides {
|
||||||
|
preferAc3Surround = value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
summaryOn = R.string.prefer_ac3_for_surround_summary,
|
||||||
|
// summaryOn = R.string.enabled,
|
||||||
|
summaryOff = R.string.disabled,
|
||||||
|
validator = { prefs, value ->
|
||||||
|
prefs.playbackPreferences.overrides.let {
|
||||||
|
if (value && !it.ac3Supported) {
|
||||||
|
PreferenceValidation.Invalid("AC3 support is not enabled")
|
||||||
|
} else if (value && it.downmixStereo) {
|
||||||
|
PreferenceValidation.Invalid("Always downmixing to stereo")
|
||||||
|
} else {
|
||||||
|
PreferenceValidation.Valid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
val DownMixStereo =
|
val DownMixStereo =
|
||||||
AppSwitchPreference<AppPreferences>(
|
AppSwitchPreference<AppPreferences>(
|
||||||
title = R.string.downmix_stereo,
|
title = R.string.downmix_stereo,
|
||||||
defaultValue = false,
|
defaultValue = false,
|
||||||
getter = { it.playbackPreferences.overrides.downmixStereo },
|
getter = { it.playbackPreferences.overrides.downmixStereo },
|
||||||
setter = { prefs, value ->
|
setter = { prefs, value ->
|
||||||
prefs.updatePlaybackOverrides { downmixStereo = value }
|
prefs.updatePlaybackOverrides {
|
||||||
|
downmixStereo = value
|
||||||
|
if (value) preferAc3Surround = false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
summaryOn = R.string.enabled,
|
summaryOn = R.string.enabled,
|
||||||
summaryOff = R.string.disabled,
|
summaryOff = R.string.disabled,
|
||||||
|
|
@ -1066,6 +1100,7 @@ private val ExoPlayerSettings =
|
||||||
AppPreference.FfmpegPreference,
|
AppPreference.FfmpegPreference,
|
||||||
AppPreference.DownMixStereo,
|
AppPreference.DownMixStereo,
|
||||||
AppPreference.Ac3Supported,
|
AppPreference.Ac3Supported,
|
||||||
|
AppPreference.PreferAc3ForSurround,
|
||||||
AppPreference.DirectPlayAss,
|
AppPreference.DirectPlayAss,
|
||||||
AppPreference.DirectPlayPgs,
|
AppPreference.DirectPlayPgs,
|
||||||
AppPreference.DirectPlayDoviProfile7,
|
AppPreference.DirectPlayDoviProfile7,
|
||||||
|
|
@ -1206,11 +1241,16 @@ data class AppSwitchPreference<Pref>(
|
||||||
override val defaultValue: Boolean,
|
override val defaultValue: Boolean,
|
||||||
override val getter: (prefs: Pref) -> Boolean,
|
override val getter: (prefs: Pref) -> Boolean,
|
||||||
override val setter: (prefs: Pref, value: Boolean) -> Pref,
|
override val setter: (prefs: Pref, value: Boolean) -> Pref,
|
||||||
val validator: (value: Boolean) -> PreferenceValidation = { PreferenceValidation.Valid },
|
val validator: (prefs: Pref, value: Boolean) -> PreferenceValidation = { _, _ -> PreferenceValidation.Valid },
|
||||||
@param:StringRes val summary: Int? = null,
|
@param:StringRes val summary: Int? = null,
|
||||||
@param:StringRes val summaryOn: Int? = null,
|
@param:StringRes val summaryOn: Int? = null,
|
||||||
@param:StringRes val summaryOff: Int? = null,
|
@param:StringRes val summaryOff: Int? = null,
|
||||||
) : AppPreference<Pref, Boolean> {
|
) : AppPreference<Pref, Boolean> {
|
||||||
|
override fun validate(
|
||||||
|
prefs: Pref,
|
||||||
|
value: Boolean,
|
||||||
|
): PreferenceValidation = validator.invoke(prefs, value)
|
||||||
|
|
||||||
override fun summary(
|
override fun summary(
|
||||||
context: Context,
|
context: Context,
|
||||||
value: Boolean?,
|
value: Boolean?,
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ class DeviceProfileService
|
||||||
pgsDirectPlay = prefs.overrides.directPlayPgs,
|
pgsDirectPlay = prefs.overrides.directPlayPgs,
|
||||||
dolbyVisionELDirectPlay = prefs.overrides.directPlayDolbyVisionEL,
|
dolbyVisionELDirectPlay = prefs.overrides.directPlayDolbyVisionEL,
|
||||||
decodeAv1 = prefs.overrides.decodeAv1,
|
decodeAv1 = prefs.overrides.decodeAv1,
|
||||||
|
preferAc3ForSurround = prefs.overrides.preferAc3Surround,
|
||||||
jellyfinTenEleven =
|
jellyfinTenEleven =
|
||||||
serverVersion != null && serverVersion >= ServerVersion(10, 11, 0),
|
serverVersion != null && serverVersion >= ServerVersion(10, 11, 0),
|
||||||
)
|
)
|
||||||
|
|
@ -59,6 +60,7 @@ class DeviceProfileService
|
||||||
pgsDirectPlay = newConfig.pgsDirectPlay,
|
pgsDirectPlay = newConfig.pgsDirectPlay,
|
||||||
dolbyVisionELDirectPlay = newConfig.dolbyVisionELDirectPlay,
|
dolbyVisionELDirectPlay = newConfig.dolbyVisionELDirectPlay,
|
||||||
decodeAv1 = prefs.overrides.decodeAv1,
|
decodeAv1 = prefs.overrides.decodeAv1,
|
||||||
|
preferAc3ForSurround = prefs.overrides.preferAc3Surround,
|
||||||
jellyfinTenEleven = newConfig.jellyfinTenEleven,
|
jellyfinTenEleven = newConfig.jellyfinTenEleven,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -78,5 +80,6 @@ data class DeviceProfileConfiguration(
|
||||||
val pgsDirectPlay: Boolean,
|
val pgsDirectPlay: Boolean,
|
||||||
val dolbyVisionELDirectPlay: Boolean,
|
val dolbyVisionELDirectPlay: Boolean,
|
||||||
val decodeAv1: Boolean,
|
val decodeAv1: Boolean,
|
||||||
|
val preferAc3ForSurround: Boolean,
|
||||||
val jellyfinTenEleven: Boolean,
|
val jellyfinTenEleven: Boolean,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -441,7 +441,7 @@ fun PreferencesContent(
|
||||||
value = value,
|
value = value,
|
||||||
onNavigate = viewModel.navigationManager::navigateTo,
|
onNavigate = viewModel.navigationManager::navigateTo,
|
||||||
onValueChange = { newValue ->
|
onValueChange = { newValue ->
|
||||||
val validation = pref.validate(newValue)
|
val validation = pref.validate(preferences, newValue)
|
||||||
when (validation) {
|
when (validation) {
|
||||||
is PreferenceValidation.Invalid -> {
|
is PreferenceValidation.Invalid -> {
|
||||||
// TODO?
|
// TODO?
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ fun SubtitlePreferencesContent(
|
||||||
value = value,
|
value = value,
|
||||||
onNavigate = viewModel.navigationManager::navigateTo,
|
onNavigate = viewModel.navigationManager::navigateTo,
|
||||||
onValueChange = { newValue ->
|
onValueChange = { newValue ->
|
||||||
val validation = pref.validate(newValue)
|
val validation = pref.validate(preferences, newValue)
|
||||||
when (validation) {
|
when (validation) {
|
||||||
is PreferenceValidation.Invalid -> {
|
is PreferenceValidation.Invalid -> {
|
||||||
// TODO?
|
// TODO?
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ fun createDeviceProfile(
|
||||||
dolbyVisionELDirectPlay: Boolean,
|
dolbyVisionELDirectPlay: Boolean,
|
||||||
decodeAv1: Boolean,
|
decodeAv1: Boolean,
|
||||||
jellyfinTenEleven: Boolean,
|
jellyfinTenEleven: Boolean,
|
||||||
|
preferAc3ForSurround: Boolean,
|
||||||
) = buildDeviceProfile {
|
) = buildDeviceProfile {
|
||||||
val allowedAudioCodecs =
|
val allowedAudioCodecs =
|
||||||
when {
|
when {
|
||||||
|
|
@ -132,6 +133,23 @@ fun createDeviceProfile(
|
||||||
|
|
||||||
// / Transcoding profiles
|
// / Transcoding profiles
|
||||||
// Video
|
// Video
|
||||||
|
if (preferAc3ForSurround) {
|
||||||
|
transcodingProfile {
|
||||||
|
type = DlnaProfileType.VIDEO
|
||||||
|
context = EncodingContext.STREAMING
|
||||||
|
|
||||||
|
container = Codec.Container.TS
|
||||||
|
protocol = MediaStreamProtocol.HLS
|
||||||
|
|
||||||
|
if (supportsHevc) videoCodec(Codec.Video.HEVC)
|
||||||
|
videoCodec(Codec.Video.H264)
|
||||||
|
|
||||||
|
audioCodec(Codec.Audio.AC3)
|
||||||
|
|
||||||
|
copyTimestamps = false
|
||||||
|
enableSubtitlesInManifest = true
|
||||||
|
}
|
||||||
|
}
|
||||||
transcodingProfile {
|
transcodingProfile {
|
||||||
type = DlnaProfileType.VIDEO
|
type = DlnaProfileType.VIDEO
|
||||||
context = EncodingContext.STREAMING
|
context = EncodingContext.STREAMING
|
||||||
|
|
@ -516,6 +534,33 @@ fun createDeviceProfile(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (preferAc3ForSurround) {
|
||||||
|
codecProfile {
|
||||||
|
type = CodecType.VIDEO_AUDIO
|
||||||
|
codec = Codec.Audio.AAC
|
||||||
|
|
||||||
|
conditions {
|
||||||
|
ProfileConditionValue.AUDIO_PROFILE equals "none"
|
||||||
|
}
|
||||||
|
|
||||||
|
applyConditions {
|
||||||
|
ProfileConditionValue.AUDIO_CHANNELS greaterThanOrEquals 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
codecProfile {
|
||||||
|
type = CodecType.VIDEO_AUDIO
|
||||||
|
codec = Codec.Audio.OPUS
|
||||||
|
|
||||||
|
conditions {
|
||||||
|
ProfileConditionValue.AUDIO_PROFILE equals "none"
|
||||||
|
}
|
||||||
|
|
||||||
|
applyConditions {
|
||||||
|
ProfileConditionValue.AUDIO_CHANNELS greaterThanOrEquals 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Audio channel profile
|
// Audio channel profile
|
||||||
codecProfile {
|
codecProfile {
|
||||||
type = CodecType.VIDEO_AUDIO
|
type = CodecType.VIDEO_AUDIO
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ message PlaybackOverrides{
|
||||||
MediaExtensionStatus media_extensions_enabled = 5;
|
MediaExtensionStatus media_extensions_enabled = 5;
|
||||||
bool direct_play_dolby_vision_e_l = 6;
|
bool direct_play_dolby_vision_e_l = 6;
|
||||||
bool decode_av1 = 7;
|
bool decode_av1 = 7;
|
||||||
|
bool prefer_ac3_surround = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
message PlaybackPreferences {
|
message PlaybackPreferences {
|
||||||
|
|
|
||||||
|
|
@ -522,6 +522,8 @@
|
||||||
<string name="display_presets">Display presets</string>
|
<string name="display_presets">Display presets</string>
|
||||||
<string name="display_presets_description">Built-in presets to quickly style all rows</string>
|
<string name="display_presets_description">Built-in presets to quickly style all rows</string>
|
||||||
<string name="customize_home_summary">Choose rows and images on the home page</string>
|
<string name="customize_home_summary">Choose rows and images on the home page</string>
|
||||||
|
<string name="prefer_ac3_for_surround_summary"><![CDATA[Transcode 2+ channel audio to AC3/Dolby Digital]]></string>
|
||||||
|
<string name="prefer_ac3_for_surround">Use AC3 for surround sound audio</string>
|
||||||
|
|
||||||
<string-array name="theme_song_volume">
|
<string-array name="theme_song_volume">
|
||||||
<item>Disabled</item>
|
<item>Disabled</item>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue