diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 2c8be5d78..bb3997a81 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -62,7 +62,6 @@ import static org.schabi.newpipe.player.helper.PlayerHelper.savePlaybackParamete import static org.schabi.newpipe.util.ListHelper.getPopupResolutionIndex; import static org.schabi.newpipe.util.ListHelper.getResolutionIndex; import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; -import static org.schabi.newpipe.util.Localization.containsCaseInsensitive; import static java.util.concurrent.TimeUnit.MILLISECONDS; import android.animation.Animator; @@ -130,6 +129,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.DefaultRenderersFactory; import com.google.android.exoplayer2.ExoPlayer; +import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.PlaybackException; import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.Player.PositionInfo; @@ -138,7 +138,6 @@ import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.TracksInfo; import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.TrackGroup; -import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.MappingTrackSelector; @@ -2530,7 +2529,7 @@ public final class Player implements Log.d(TAG, "ExoPlayer - onTracksChanged(), " + "track group size = " + tracksInfo.getTrackGroupInfos().size()); } - onTextTracksChanged(); + onTextTracksChanged(tracksInfo); } @Override @@ -3516,17 +3515,7 @@ public final class Player implements return; } captionPopupMenu.getMenu().removeGroup(POPUP_MENU_ID_CAPTION); - - final String userPreferredLanguage = - prefs.getString(context.getString(R.string.caption_user_set_key), null); - /* - * only search for autogenerated cc as fallback - * if "(auto-generated)" was not already selected - * we are only looking for "(" instead of "(auto-generated)" to hopefully get all - * internationalized variants such as "(automatisch-erzeugt)" and so on - */ - boolean searchForAutogenerated = userPreferredLanguage != null - && !userPreferredLanguage.contains("("); + captionPopupMenu.setOnDismissListener(this); // Add option for turning off caption final MenuItem captionOffItem = captionPopupMenu.getMenu().add(POPUP_MENU_ID_CAPTION, @@ -3549,6 +3538,9 @@ public final class Player implements captionItem.setOnMenuItemClickListener(menuItem -> { final int textRendererIndex = getCaptionRendererIndex(); if (textRendererIndex != RENDERER_UNAVAILABLE) { + // DefaultTrackSelector will select for tracks with similar language names + // if a track of userPreferredLanguage is not found + // This means (auto-generated) will be resolved automatically. trackSelector.setParameters(trackSelector.buildUponParameters() .setPreferredTextLanguage(captionLanguage) .setRendererDisabled(textRendererIndex, false)); @@ -3557,22 +3549,23 @@ public final class Player implements } return true; }); - // apply caption language from previous user preference - if (userPreferredLanguage != null - && (captionLanguage.equals(userPreferredLanguage) - || (searchForAutogenerated && captionLanguage.startsWith(userPreferredLanguage)) - || (userPreferredLanguage.contains("(") && captionLanguage.startsWith( - userPreferredLanguage.substring(0, userPreferredLanguage.indexOf('(')))))) { - final int textRendererIndex = getCaptionRendererIndex(); - if (textRendererIndex != RENDERER_UNAVAILABLE) { - trackSelector.setParameters(trackSelector.buildUponParameters() - .setPreferredTextLanguage(captionLanguage) - .setRendererDisabled(textRendererIndex, false)); - } - searchForAutogenerated = false; - } } - captionPopupMenu.setOnDismissListener(this); + + // apply caption language from previous user preference + final List selectedPreferredLanguages = + trackSelector.getParameters().preferredTextLanguages; + final String userPreferredLanguage = + prefs.getString(context.getString(R.string.caption_user_set_key), null); + final int textRendererIndex = getCaptionRendererIndex(); + + if (userPreferredLanguage != null + && availableLanguages.contains(userPreferredLanguage) + && !selectedPreferredLanguages.contains(userPreferredLanguage) + && textRendererIndex != RENDERER_UNAVAILABLE) { + trackSelector.setParameters(trackSelector.buildUponParameters() + .setPreferredTextLanguage(userPreferredLanguage) + .setRendererDisabled(textRendererIndex, false)); + } } /** @@ -3668,41 +3661,45 @@ public final class Player implements binding.subtitleView.setStyle(captionStyle); } - private void onTextTracksChanged() { - final int textRenderer = getCaptionRendererIndex(); - + private void onTextTracksChanged(@NonNull final TracksInfo currentTrackInfo) { if (binding == null) { return; } + if (trackSelector.getCurrentMappedTrackInfo() == null - || textRenderer == RENDERER_UNAVAILABLE) { + || !currentTrackInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_TEXT)) { binding.captionTextView.setVisibility(View.GONE); return; } - final TrackGroupArray textTracks = trackSelector.getCurrentMappedTrackInfo() - .getTrackGroups(textRenderer); - // Extract all loaded languages - final List availableLanguages = new ArrayList<>(textTracks.length); - for (int i = 0; i < textTracks.length; i++) { - final TrackGroup textTrack = textTracks.get(i); + final List textTracks = currentTrackInfo + .getTrackGroupInfos() + .stream() + .filter(trackGroupInfo -> C.TRACK_TYPE_TEXT == trackGroupInfo.getTrackType()) + .collect(Collectors.toList()); + final List availableLanguages = new ArrayList<>(textTracks.size()); + for (int i = 0; i < textTracks.size(); i++) { + final TrackGroup textTrack = textTracks.get(i).getTrackGroup(); if (textTrack.length > 0) { availableLanguages.add(textTrack.getFormat(0).language); } } - // Normalize mismatching language strings - final String preferredLanguage = trackSelector.getParameters() - .preferredTextLanguages.stream().findFirst().orElse(null); + // Find selected text track + final Optional selectedTracks = textTracks.stream() + .filter(TracksInfo.TrackGroupInfo::isSelected) + .filter(info -> info.getTrackGroup().length >= 1) + .map(info -> info.getTrackGroup().getFormat(0)) + .findFirst(); + // Build UI buildCaptionMenu(availableLanguages); - if (trackSelector.getParameters().getRendererDisabled(textRenderer) - || preferredLanguage == null || (!availableLanguages.contains(preferredLanguage) - && !containsCaseInsensitive(availableLanguages, preferredLanguage))) { + if (trackSelector.getParameters().getRendererDisabled(getCaptionRendererIndex()) + || !selectedTracks.isPresent()) { binding.captionTextView.setText(R.string.caption_none); } else { - binding.captionTextView.setText(preferredLanguage); + binding.captionTextView.setText(selectedTracks.get().language); } binding.captionTextView.setVisibility( availableLanguages.isEmpty() ? View.GONE : View.VISIBLE);