fix: group subtitles by language - #3127
Conversation
refirestream
commented
Aug 17, 2026
- Group subtitle tracks by language name derived from IETF tag instead of raw originalName (e.g. "fr" and "French [SUB]" now land in the same "French" group)
- Fall back to "Unknown" group when language cannot be resolved
- Label tracks within a group by originalName instead of nameSuffix
- Filter subtitles by IETF tag match instead of name substring, matching primary subtag so regional variants (pt-br) match (pt)
- Keep subtitles with unresolvable language instead of dropping them (goes into the Unknown group)
- Group subtitle tracks by language name derived from IETF tag instead of raw originalName (e.g. "fr" and "French [SUB]" now land in the same "French" group) - Fall back to "Unknown" group when language cannot be resolved - Label tracks within a group by originalName instead of nameSuffix - Filter subtitles by IETF tag match instead of name substring, matching primary subtag so regional variants (pt-br) match (pt) - Keep subtitles with unresolvable language instead of dropping them - Only exempt DOWNLOADED_FILE from filtering so embedded tracks are also filtered across player reloads - Use getApiProviderLangSettings + fromCodeToLangTagIETF for proper tag normalization in the filter list
|
Doing this pull request, I discovered that there is a setting to filter out "useless" languages in : People that have not selected the correct languages during setup might be annoyed though. If we enable the "Filter by preferred media language" setting now, will it change the value for existing users ? |
|
I tested the app manually and its working well |
fire-light42
left a comment
There was a problem hiding this comment.
Good idea and minimal code changes, but needs some small changes.
|
|
||
| val unknownGroupName = ctx.getString(R.string.subtitles_group_unknown) | ||
| fun groupName(sub: SubtitleData): String { | ||
| return fromTagToLanguageName(sub.getIETF_tag())?.takeIf { it.isNotBlank() } |
There was a problem hiding this comment.
I would prefer if you save the results to a list instead of calling this function since:
-
Calling the function again creates an assumption that the function will always return the same value, which can lead to bugs when refactoring in the future.
-
I dislike calling potentially expensive functions unnecessarily.
| .getOrNull(subtitleGroupIndex - 1)?.value?.map { subtitle -> | ||
| val nameSuffix = subtitle.nameSuffix.html() | ||
| nameSuffix.ifBlank { | ||
| val label = subtitle.originalName.html() |
There was a problem hiding this comment.
This completely breaks the subtitle suffix system and makes it very confusing to precisely select between different subtitles of the same language. Is there any reason for this change?
Changing default behavior needs a lot of motivation, since users have come to expect that this is how CloudStream works. I think it would be too confusing. I would rather recommend a more subtle and visible solution, for example always placing preferred languages at the top of subtitle languages. However, this is best done as a separate pull request.
It would change the value for all users who have not previously changed the value, unless it is explicitly migrated using code. |