Merge pull request #2697 from Redirion/exoplayer2105
Update to ExoPlayer 2.10.5
This commit is contained in:
commit
28ed9879aa
|
@ -44,10 +44,10 @@ android {
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
androidxLibVersion = '1.0.0'
|
androidxLibVersion = '1.0.0'
|
||||||
exoPlayerLibVersion = '2.9.6' //2.10.5
|
exoPlayerLibVersion = '2.10.5'
|
||||||
roomDbLibVersion = '2.1.0'
|
roomDbLibVersion = '2.1.0'
|
||||||
leakCanaryLibVersion = '1.5.4' //1.6.1
|
leakCanaryLibVersion = '1.5.4' //1.6.1
|
||||||
okHttpLibVersion = '3.12.1'
|
okHttpLibVersion = '3.12.5' //3.12.6
|
||||||
icepickLibVersion = '3.2.0'
|
icepickLibVersion = '3.2.0'
|
||||||
stethoLibVersion = '1.5.0'
|
stethoLibVersion = '1.5.0'
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,17 +28,7 @@ import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import com.google.android.material.navigation.NavigationView;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.core.view.GravityCompat;
|
|
||||||
import androidx.drawerlayout.widget.DrawerLayout;
|
|
||||||
import androidx.appcompat.app.ActionBar;
|
|
||||||
import androidx.appcompat.app.ActionBarDrawerToggle;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
@ -49,6 +39,17 @@ import android.widget.Button;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.ActionBar;
|
||||||
|
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import androidx.core.view.GravityCompat;
|
||||||
|
import androidx.drawerlayout.widget.DrawerLayout;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
|
import com.google.android.material.navigation.NavigationView;
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
|
@ -361,7 +362,7 @@ public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
// close drawer on return, and don't show animation, so its looks like the drawer isn't open
|
// close drawer on return, and don't show animation, so its looks like the drawer isn't open
|
||||||
// when the user returns to MainActivity
|
// when the user returns to MainActivity
|
||||||
drawer.closeDrawer(Gravity.START, false);
|
drawer.closeDrawer(GravityCompat.START, false);
|
||||||
try {
|
try {
|
||||||
String selectedServiceName = NewPipe.getService(
|
String selectedServiceName = NewPipe.getService(
|
||||||
ServiceHelper.getSelectedServiceId(this)).getServiceInfo().getName();
|
ServiceHelper.getSelectedServiceId(this)).getServiceInfo().getName();
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
package org.schabi.newpipe.fragments;
|
package org.schabi.newpipe.fragments;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import com.google.android.material.tabs.TabLayout;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.fragment.app.FragmentManager;
|
|
||||||
import androidx.fragment.app.FragmentPagerAdapter;
|
|
||||||
import androidx.viewpager.widget.ViewPager;
|
|
||||||
import androidx.appcompat.app.ActionBar;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
|
@ -18,6 +9,17 @@ import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.ActionBar;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentPagerAdapter;
|
||||||
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
|
||||||
import org.schabi.newpipe.BaseFragment;
|
import org.schabi.newpipe.BaseFragment;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
|
@ -111,8 +113,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
tabsManager.unsetSavedTabsListener();
|
tabsManager.unsetSavedTabsListener();
|
||||||
pagerAdapter = null;
|
if (viewPager != null) viewPager.setAdapter(null);
|
||||||
viewPager.setAdapter(pagerAdapter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package org.schabi.newpipe.fragments.list;
|
package org.schabi.newpipe.fragments.list;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.ListExtractor;
|
import org.schabi.newpipe.extractor.ListExtractor;
|
||||||
import org.schabi.newpipe.extractor.ListInfo;
|
import org.schabi.newpipe.extractor.ListInfo;
|
||||||
import org.schabi.newpipe.util.Constants;
|
import org.schabi.newpipe.util.Constants;
|
||||||
|
@ -61,8 +62,10 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
if (currentWorker != null) currentWorker.dispose();
|
if (currentWorker != null) {
|
||||||
currentWorker = null;
|
currentWorker.dispose();
|
||||||
|
currentWorker = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -28,12 +28,13 @@ import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.android.exoplayer2.DefaultRenderersFactory;
|
import com.google.android.exoplayer2.DefaultRenderersFactory;
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
import com.google.android.exoplayer2.ExoPlayerFactory;
|
||||||
|
@ -209,7 +210,7 @@ public abstract class BasePlayer implements
|
||||||
this.databaseUpdateReactor = new CompositeDisposable();
|
this.databaseUpdateReactor = new CompositeDisposable();
|
||||||
|
|
||||||
final String userAgent = Downloader.USER_AGENT;
|
final String userAgent = Downloader.USER_AGENT;
|
||||||
final DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
|
final DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter.Builder(context).build();
|
||||||
this.dataSource = new PlayerDataSource(context, userAgent, bandwidthMeter);
|
this.dataSource = new PlayerDataSource(context, userAgent, bandwidthMeter);
|
||||||
|
|
||||||
final TrackSelection.Factory trackSelectionFactory = PlayerHelper.getQualitySelector(context);
|
final TrackSelection.Factory trackSelectionFactory = PlayerHelper.getQualitySelector(context);
|
||||||
|
@ -1193,10 +1194,7 @@ public abstract class BasePlayer implements
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPlaying() {
|
public boolean isPlaying() {
|
||||||
if (simpleExoPlayer == null) return false;
|
return simpleExoPlayer != null && simpleExoPlayer.isPlaying();
|
||||||
final int state = simpleExoPlayer.getPlaybackState();
|
|
||||||
return (state == Player.STATE_READY || state == Player.STATE_BUFFERING)
|
|
||||||
&& simpleExoPlayer.getPlayWhenReady();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Player.RepeatMode
|
@Player.RepeatMode
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package org.schabi.newpipe.player.helper;
|
package org.schabi.newpipe.player.helper;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.database.ExoDatabaseProvider;
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
import com.google.android.exoplayer2.upstream.DefaultDataSource;
|
import com.google.android.exoplayer2.upstream.DefaultDataSource;
|
||||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||||
|
@ -54,7 +56,7 @@ import java.io.File;
|
||||||
|
|
||||||
if (cache == null) {
|
if (cache == null) {
|
||||||
final LeastRecentlyUsedCacheEvictor evictor = new LeastRecentlyUsedCacheEvictor(maxCacheSize);
|
final LeastRecentlyUsedCacheEvictor evictor = new LeastRecentlyUsedCacheEvictor(maxCacheSize);
|
||||||
cache = new SimpleCache(cacheDir, evictor);
|
cache = new SimpleCache(cacheDir, evictor, new ExoDatabaseProvider(context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,12 @@ package org.schabi.newpipe.player.helper;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.support.v4.media.session.MediaSessionCompat;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media.session.MediaButtonReceiver;
|
import androidx.media.session.MediaButtonReceiver;
|
||||||
import android.support.v4.media.session.MediaSessionCompat;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
|
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
|
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
|
||||||
|
@ -27,10 +28,10 @@ public class MediaSessionManager {
|
||||||
this.mediaSession = new MediaSessionCompat(context, TAG);
|
this.mediaSession = new MediaSessionCompat(context, TAG);
|
||||||
this.mediaSession.setActive(true);
|
this.mediaSession.setActive(true);
|
||||||
|
|
||||||
this.sessionConnector = new MediaSessionConnector(mediaSession,
|
this.sessionConnector = new MediaSessionConnector(mediaSession);
|
||||||
new PlayQueuePlaybackController(callback));
|
this.sessionConnector.setControlDispatcher(new PlayQueuePlaybackController(callback));
|
||||||
this.sessionConnector.setQueueNavigator(new PlayQueueNavigator(mediaSession, callback));
|
this.sessionConnector.setQueueNavigator(new PlayQueueNavigator(mediaSession, callback));
|
||||||
this.sessionConnector.setPlayer(player, null);
|
this.sessionConnector.setPlayer(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -43,7 +44,7 @@ public class MediaSessionManager {
|
||||||
* Should be called on player destruction to prevent leakage.
|
* Should be called on player destruction to prevent leakage.
|
||||||
* */
|
* */
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
this.sessionConnector.setPlayer(null, null);
|
this.sessionConnector.setPlayer(null);
|
||||||
this.sessionConnector.setQueueNavigator(null);
|
this.sessionConnector.setQueueNavigator(null);
|
||||||
this.mediaSession.setActive(false);
|
this.mediaSession.setActive(false);
|
||||||
this.mediaSession.release();
|
this.mediaSession.release();
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package org.schabi.newpipe.player.helper;
|
package org.schabi.newpipe.player.helper;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.google.android.exoplayer2.source.ExtractorMediaSource;
|
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
||||||
import com.google.android.exoplayer2.source.SingleSampleMediaSource;
|
import com.google.android.exoplayer2.source.SingleSampleMediaSource;
|
||||||
import com.google.android.exoplayer2.source.dash.DashMediaSource;
|
import com.google.android.exoplayer2.source.dash.DashMediaSource;
|
||||||
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
|
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
|
||||||
|
@ -64,12 +65,12 @@ public class PlayerDataSource {
|
||||||
cacheDataSourceFactory), cacheDataSourceFactory);
|
cacheDataSourceFactory), cacheDataSourceFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtractorMediaSource.Factory getExtractorMediaSourceFactory() {
|
public ProgressiveMediaSource.Factory getExtractorMediaSourceFactory() {
|
||||||
return new ExtractorMediaSource.Factory(cacheDataSourceFactory)
|
return new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
|
||||||
.setLoadErrorHandlingPolicy(new DefaultLoadErrorHandlingPolicy(EXTRACTOR_MINIMUM_RETRY));
|
.setLoadErrorHandlingPolicy(new DefaultLoadErrorHandlingPolicy(EXTRACTOR_MINIMUM_RETRY));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtractorMediaSource.Factory getExtractorMediaSourceFactory(@NonNull final String key) {
|
public ProgressiveMediaSource.Factory getExtractorMediaSourceFactory(@NonNull final String key) {
|
||||||
return getExtractorMediaSourceFactory().setCustomCacheKey(key);
|
return getExtractorMediaSourceFactory().setCustomCacheKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,12 @@ package org.schabi.newpipe.player.mediasession;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.ResultReceiver;
|
import android.os.ResultReceiver;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import android.support.v4.media.session.MediaSessionCompat;
|
import android.support.v4.media.session.MediaSessionCompat;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.ControlDispatcher;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
|
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
@ -63,17 +65,17 @@ public class PlayQueueNavigator implements MediaSessionConnector.QueueNavigator
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSkipToPrevious(Player player) {
|
public void onSkipToPrevious(Player player, ControlDispatcher controlDispatcher) {
|
||||||
callback.onSkipToPrevious();
|
callback.onSkipToPrevious();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSkipToQueueItem(Player player, long id) {
|
public void onSkipToQueueItem(Player player, ControlDispatcher controlDispatcher, long id) {
|
||||||
callback.onSkipToIndex((int) id);
|
callback.onSkipToIndex((int) id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSkipToNext(Player player) {
|
public void onSkipToNext(Player player, ControlDispatcher controlDispatcher) {
|
||||||
callback.onSkipToNext();
|
callback.onSkipToNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,12 +102,7 @@ public class PlayQueueNavigator implements MediaSessionConnector.QueueNavigator
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getCommands() {
|
public boolean onCommand(Player player, ControlDispatcher controlDispatcher, String command, Bundle extras, ResultReceiver cb) {
|
||||||
return new String[0];
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCommand(Player player, String command, Bundle extras, ResultReceiver cb) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package org.schabi.newpipe.player.mediasession;
|
package org.schabi.newpipe.player.mediasession;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.DefaultControlDispatcher;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.ext.mediasession.DefaultPlaybackController;
|
|
||||||
|
|
||||||
public class PlayQueuePlaybackController extends DefaultPlaybackController {
|
public class PlayQueuePlaybackController extends DefaultControlDispatcher {
|
||||||
private final MediaSessionCallback callback;
|
private final MediaSessionCallback callback;
|
||||||
|
|
||||||
public PlayQueuePlaybackController(final MediaSessionCallback callback) {
|
public PlayQueuePlaybackController(final MediaSessionCallback callback) {
|
||||||
|
@ -12,12 +12,12 @@ public class PlayQueuePlaybackController extends DefaultPlaybackController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlay(Player player) {
|
public boolean dispatchSetPlayWhenReady(Player player, boolean playWhenReady) {
|
||||||
callback.onPlay();
|
if (playWhenReady) {
|
||||||
}
|
callback.onPlay();
|
||||||
|
} else {
|
||||||
@Override
|
callback.onPause();
|
||||||
public void onPause(Player player) {
|
}
|
||||||
callback.onPause();
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
package org.schabi.newpipe.player.playback;
|
package org.schabi.newpipe.player.playback;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.source.TrackGroup;
|
import com.google.android.exoplayer2.source.TrackGroup;
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||||
import com.google.android.exoplayer2.trackselection.FixedTrackSelection;
|
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
|
|
||||||
|
@ -21,7 +23,6 @@ import com.google.android.exoplayer2.util.Assertions;
|
||||||
* a broader set of languages.
|
* a broader set of languages.
|
||||||
* */
|
* */
|
||||||
public class CustomTrackSelector extends DefaultTrackSelector {
|
public class CustomTrackSelector extends DefaultTrackSelector {
|
||||||
private static final int WITHIN_RENDERER_CAPABILITIES_BONUS = 1000;
|
|
||||||
|
|
||||||
private String preferredTextLanguage;
|
private String preferredTextLanguage;
|
||||||
|
|
||||||
|
@ -41,23 +42,22 @@ public class CustomTrackSelector extends DefaultTrackSelector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @see DefaultTrackSelector#formatHasLanguage(Format, String)*/
|
private static boolean formatHasLanguage(Format format, String language) {
|
||||||
protected static boolean formatHasLanguage(Format format, String language) {
|
|
||||||
return language != null && TextUtils.equals(language, format.language);
|
return language != null && TextUtils.equals(language, format.language);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @see DefaultTrackSelector#formatHasNoLanguage(Format)*/
|
|
||||||
protected static boolean formatHasNoLanguage(Format format) {
|
|
||||||
return TextUtils.isEmpty(format.language) || formatHasLanguage(format, C.LANGUAGE_UNDETERMINED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @see DefaultTrackSelector#selectTextTrack(TrackGroupArray, int[][], Parameters) */
|
|
||||||
@Override
|
@Override
|
||||||
protected Pair<TrackSelection, Integer> selectTextTrack(TrackGroupArray groups, int[][] formatSupport,
|
@Nullable
|
||||||
Parameters params) {
|
protected Pair<TrackSelection.Definition, TextTrackScore> selectTextTrack(
|
||||||
|
TrackGroupArray groups,
|
||||||
|
int[][] formatSupport,
|
||||||
|
Parameters params,
|
||||||
|
@Nullable String selectedAudioLanguage)
|
||||||
|
throws ExoPlaybackException {
|
||||||
TrackGroup selectedGroup = null;
|
TrackGroup selectedGroup = null;
|
||||||
int selectedTrackIndex = 0;
|
int selectedTrackIndex = C.INDEX_UNSET;
|
||||||
int selectedTrackScore = 0;
|
int newPipeTrackScore = 0;
|
||||||
|
TextTrackScore selectedTrackScore = null;
|
||||||
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
|
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
|
||||||
TrackGroup trackGroup = groups.get(groupIndex);
|
TrackGroup trackGroup = groups.get(groupIndex);
|
||||||
int[] trackFormatSupport = formatSupport[groupIndex];
|
int[] trackFormatSupport = formatSupport[groupIndex];
|
||||||
|
@ -65,41 +65,17 @@ public class CustomTrackSelector extends DefaultTrackSelector {
|
||||||
if (isSupported(trackFormatSupport[trackIndex],
|
if (isSupported(trackFormatSupport[trackIndex],
|
||||||
params.exceedRendererCapabilitiesIfNecessary)) {
|
params.exceedRendererCapabilitiesIfNecessary)) {
|
||||||
Format format = trackGroup.getFormat(trackIndex);
|
Format format = trackGroup.getFormat(trackIndex);
|
||||||
int maskedSelectionFlags =
|
TextTrackScore trackScore =
|
||||||
format.selectionFlags & ~params.disabledTextTrackSelectionFlags;
|
new TextTrackScore(
|
||||||
boolean isDefault = (maskedSelectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
|
format, params, trackFormatSupport[trackIndex], selectedAudioLanguage);
|
||||||
boolean isForced = (maskedSelectionFlags & C.SELECTION_FLAG_FORCED) != 0;
|
if (formatHasLanguage(format, preferredTextLanguage)) {
|
||||||
int trackScore;
|
selectedGroup = trackGroup;
|
||||||
boolean preferredLanguageFound = formatHasLanguage(format, preferredTextLanguage);
|
selectedTrackIndex = trackIndex;
|
||||||
if (preferredLanguageFound
|
selectedTrackScore = trackScore;
|
||||||
|| (params.selectUndeterminedTextLanguage && formatHasNoLanguage(format))) {
|
// found user selected match (perfect!)
|
||||||
if (isDefault) {
|
break;
|
||||||
trackScore = 8;
|
} else if (trackScore.isWithinConstraints
|
||||||
} else if (!isForced) {
|
&& (selectedTrackScore == null || trackScore.compareTo(selectedTrackScore) > 0)) {
|
||||||
// Prefer non-forced to forced if a preferred text language has been specified. Where
|
|
||||||
// both are provided the non-forced track will usually contain the forced subtitles as
|
|
||||||
// a subset.
|
|
||||||
trackScore = 6;
|
|
||||||
} else {
|
|
||||||
trackScore = 4;
|
|
||||||
}
|
|
||||||
trackScore += preferredLanguageFound ? 1 : 0;
|
|
||||||
} else if (isDefault) {
|
|
||||||
trackScore = 3;
|
|
||||||
} else if (isForced) {
|
|
||||||
if (formatHasLanguage(format, params.preferredAudioLanguage)) {
|
|
||||||
trackScore = 2;
|
|
||||||
} else {
|
|
||||||
trackScore = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Track should not be selected.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (isSupported(trackFormatSupport[trackIndex], false)) {
|
|
||||||
trackScore += WITHIN_RENDERER_CAPABILITIES_BONUS;
|
|
||||||
}
|
|
||||||
if (trackScore > selectedTrackScore) {
|
|
||||||
selectedGroup = trackGroup;
|
selectedGroup = trackGroup;
|
||||||
selectedTrackIndex = trackIndex;
|
selectedTrackIndex = trackIndex;
|
||||||
selectedTrackScore = trackScore;
|
selectedTrackScore = trackScore;
|
||||||
|
@ -110,6 +86,7 @@ public class CustomTrackSelector extends DefaultTrackSelector {
|
||||||
return selectedGroup == null
|
return selectedGroup == null
|
||||||
? null
|
? null
|
||||||
: Pair.create(
|
: Pair.create(
|
||||||
new FixedTrackSelection(selectedGroup, selectedTrackIndex), selectedTrackScore);
|
new TrackSelection.Definition(selectedGroup, selectedTrackIndex),
|
||||||
|
Assertions.checkNotNull(selectedTrackScore));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@ buildscript {
|
||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.2.0'
|
classpath 'com.android.tools.build:gradle:3.4.0'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#Sun Sep 22 10:40:45 CEST 2019
|
#Mon Oct 07 06:29:33 CEST 2019
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
|
||||||
|
|
Loading…
Reference in New Issue