Skip to content

Commit

Permalink
Add SPDIF output mode
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelRUSF committed Aug 26, 2024
1 parent b116db0 commit 4ec5bc4
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,9 @@ enum class AudioBehavior(
* Downnmix audio to stereo. Disables the AC3, EAC3 and AAC_LATM audio codecs.
*/
DOWNMIX_TO_STEREO(R.string.pref_audio_compat),

/**
* Allow only the AC3, EAC3 and DTS codecs. All others capped to stereo output
*/
SPDIF_OUTPUT(R.string.audio_spdif)
}
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,8 @@ private VideoOptions buildExoPlayerOptions(@Nullable Integer forcedSubtitleIndex
isLiveTv && !userPreferences.getValue().get(UserPreferences.Companion.getLiveTvDirectPlayEnabled()),
userPreferences.getValue().get(UserPreferences.Companion.getAc3Enabled()),
userPreferences.getValue().get(UserPreferences.Companion.getAudioBehaviour()) == AudioBehavior.DOWNMIX_TO_STEREO,
!DeviceUtils.has4kVideoSupport()
!DeviceUtils.has4kVideoSupport(),
userPreferences.getValue().get(UserPreferences.Companion.getAudioBehaviour()) == AudioBehavior.SPDIF_OUTPUT
);
internalOptions.setProfile(internalProfile);
return internalOptions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.jellyfin.androidtv.util.profile.ProfileHelper.deviceHevcCodecProfile
import org.jellyfin.androidtv.util.profile.ProfileHelper.deviceHevcLevelCodecProfiles
import org.jellyfin.androidtv.util.profile.ProfileHelper.max1080pProfileConditions
import org.jellyfin.androidtv.util.profile.ProfileHelper.maxAudioChannelsCodecProfile
import org.jellyfin.androidtv.util.profile.ProfileHelper.maxSPDIFAudioChannelProfile
import org.jellyfin.androidtv.util.profile.ProfileHelper.photoDirectPlayProfile
import org.jellyfin.androidtv.util.profile.ProfileHelper.subtitleProfile
import org.jellyfin.androidtv.util.profile.ProfileHelper.supportsHevc
Expand All @@ -28,28 +29,40 @@ class ExoPlayerProfile(
disableVideoDirectPlay: Boolean,
isAC3Enabled: Boolean,
downMixAudio: Boolean,
disable4KVideo: Boolean
disable4KVideo: Boolean,
enableSPDIF: Boolean
) : DeviceProfile() {
private val downmixSupportedAudioCodecs = arrayOf(
Codec.Audio.AAC,
Codec.Audio.MP3,
Codec.Audio.MP2
)

private val downmixSPDIFSupportedAudioCodecs = arrayOf(
// Bypass isAC3Enabled check for SPDIF
Codec.Audio.AC3,
Codec.Audio.MP3,
Codec.Audio.MP2
)

/**
* Returns all audio codecs used commonly in video containers.
* This does not include containers / codecs found in audio files
*/
private val allSupportedAudioCodecs = buildList {
addAll(downmixSupportedAudioCodecs)
if ((isAC3Enabled) || (enableSPDIF)) {
add(Codec.Audio.AC3)
add(Codec.Audio.EAC3)
}
if (!enableSPDIF) {
add(Codec.Audio.MLP)
add(Codec.Audio.TRUEHD)
}
add(Codec.Audio.AAC_LATM)
add(Codec.Audio.ALAC)
if (isAC3Enabled) add(Codec.Audio.AC3)
if (isAC3Enabled) add(Codec.Audio.EAC3)
add(Codec.Audio.DCA)
add(Codec.Audio.DTS)
add(Codec.Audio.MLP)
add(Codec.Audio.TRUEHD)
add(Codec.Audio.PCM_ALAW)
add(Codec.Audio.PCM_MULAW)
add(Codec.Audio.PCM_S16LE)
Expand All @@ -70,6 +83,18 @@ class ExoPlayerProfile(
maxStreamingBitrate = 20_000_000 // 20 mbps
maxStaticBitrate = 10_000_0000 // 10 mbps

// Determine audio codecs for profiles
val audioCodecForTranscodingProfile = when {
downMixAudio -> downmixSupportedAudioCodecs
enableSPDIF -> downmixSPDIFSupportedAudioCodecs
else -> allSupportedAudioCodecsWithoutFFmpegExperimental
}.joinToString(",")

val audioCodecForDirectPlayProfile = when {
downMixAudio -> downmixSupportedAudioCodecs
else -> allSupportedAudioCodecsWithoutFFmpegExperimental
}.joinToString(",")

transcodingProfiles = arrayOf(
// TS video profile
TranscodingProfile().apply {
Expand All @@ -80,10 +105,7 @@ class ExoPlayerProfile(
if (supportsHevc) add(Codec.Video.HEVC)
add(Codec.Video.H264)
}.joinToString(",")
audioCodec = when (downMixAudio) {
true -> downmixSupportedAudioCodecs
false -> allSupportedAudioCodecsWithoutFFmpegExperimental
}.joinToString(",")
audioCodec = audioCodecForTranscodingProfile
protocol = "hls"
copyTimestamps = false
},
Expand Down Expand Up @@ -128,10 +150,7 @@ class ExoPlayerProfile(
Codec.Video.AV1
).joinToString(",")

audioCodec = when (downMixAudio) {
true -> downmixSupportedAudioCodecs
false -> allSupportedAudioCodecs
}.joinToString(",")
audioCodec = audioCodecForDirectPlayProfile
})
}
// Audio direct play
Expand Down Expand Up @@ -208,6 +227,24 @@ class ExoPlayerProfile(
}
// Audio channel profile
add(maxAudioChannelsCodecProfile(channels = if (downMixAudio) 2 else 8))
// Add maximum audio channel profiles for SPDIF if enableSPDIF is true
if (enableSPDIF) {
arrayOf(
Codec.Audio.AAC,
Codec.Audio.AAC_LATM,
Codec.Audio.ALAC,
Codec.Audio.PCM_ALAW,
Codec.Audio.PCM_MULAW,
Codec.Audio.PCM_S16LE,
Codec.Audio.PCM_S20LE,
Codec.Audio.PCM_S24LE,
Codec.Audio.OPUS,
Codec.Audio.FLAC,
Codec.Audio.VORBIS
).forEach { codec ->
add(maxSPDIFAudioChannelProfile(codec, 2))
}
}
}.toTypedArray()

subtitleProfiles = arrayOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,20 @@ object ProfileHelper {
)
}

fun maxSPDIFAudioChannelProfile(codec: String, maxChannels: Int): CodecProfile {
return CodecProfile().apply {
type = CodecType.VideoAudio
this.codec = codec
conditions = arrayOf(
ProfileCondition(
ProfileConditionType.LessThanEqual,
ProfileConditionValue.AudioChannels,
maxChannels.toString()
)
)
}
}

internal fun subtitleProfile(
format: String,
method: SubtitleDeliveryMethod
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@
<string name="past_week">Past week</string>
<string name="scheduled_in_next_24_hours">Scheduled in next 24 hours</string>
<string name="past_24_hours">Past 24 hours</string>
<string name="audio_spdif">SPDIF</string>
<plurals name="seconds">
<item quantity="one">%1$s second</item>
<item quantity="other">%1$s seconds</item>
Expand Down

0 comments on commit 4ec5bc4

Please sign in to comment.