Merge pull request #4001 from ByteHamster/select-audio-tracks
Allow to select audio track
This commit is contained in:
commit
77efea895a
@ -2,6 +2,8 @@ package de.danoeh.antennapod.dialog;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
@ -17,6 +19,8 @@ import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||
import de.danoeh.antennapod.core.util.playback.PlaybackController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PlaybackControlsDialog extends DialogFragment {
|
||||
private static final String ARGUMENT_IS_PLAYING_VIDEO = "isPlayingVideo";
|
||||
|
||||
@ -43,6 +47,7 @@ public class PlaybackControlsDialog extends DialogFragment {
|
||||
@Override
|
||||
public void setupGUI() {
|
||||
setupUi();
|
||||
setupAudioTracks();
|
||||
}
|
||||
};
|
||||
controller.init();
|
||||
@ -198,6 +203,23 @@ public class PlaybackControlsDialog extends DialogFragment {
|
||||
});
|
||||
}
|
||||
|
||||
private void setupAudioTracks() {
|
||||
List<String> audioTracks = controller.getAudioTracks();
|
||||
int selectedAudioTrack = controller.getSelectedAudioTrack();
|
||||
final Button butAudioTracks = dialog.findViewById(R.id.audio_tracks);
|
||||
if (audioTracks.size() < 2 || selectedAudioTrack < 0) {
|
||||
butAudioTracks.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
butAudioTracks.setVisibility(View.VISIBLE);
|
||||
butAudioTracks.setText(audioTracks.get(selectedAudioTrack));
|
||||
butAudioTracks.setOnClickListener(v -> {
|
||||
controller.setAudioTrack((selectedAudioTrack + 1) % audioTracks.size());
|
||||
new Handler().postDelayed(this::setupAudioTracks, 500);
|
||||
});
|
||||
}
|
||||
|
||||
private float getCurrentSpeed() {
|
||||
Playable media = null;
|
||||
if (controller != null) {
|
||||
|
@ -11,6 +11,13 @@
|
||||
android:minWidth="300dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<Button
|
||||
android:id="@+id/audio_tracks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -9,6 +9,7 @@ import com.google.android.exoplayer2.DefaultLoadControl;
|
||||
import com.google.android.exoplayer2.DefaultRenderersFactory;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.SeekParameters;
|
||||
@ -17,7 +18,13 @@ import com.google.android.exoplayer2.audio.AudioAttributes;
|
||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.ui.DefaultTrackNameProvider;
|
||||
import com.google.android.exoplayer2.ui.TrackNameProvider;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
|
||||
@ -30,6 +37,9 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import org.antennapod.audio.MediaPlayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ExoPlayerWrapper implements IPlayer {
|
||||
@ -45,11 +55,11 @@ public class ExoPlayerWrapper implements IPlayer {
|
||||
private MediaPlayer.OnBufferingUpdateListener bufferingUpdateListener;
|
||||
private PlaybackParameters playbackParameters;
|
||||
private MediaPlayer.OnInfoListener infoListener;
|
||||
|
||||
private DefaultTrackSelector trackSelector;
|
||||
|
||||
ExoPlayerWrapper(Context context) {
|
||||
this.context = context;
|
||||
exoPlayer = createPlayer();
|
||||
createPlayer();
|
||||
playbackParameters = exoPlayer.getPlaybackParameters();
|
||||
bufferingUpdateDisposable = Observable.interval(2, TimeUnit.SECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@ -60,16 +70,17 @@ public class ExoPlayerWrapper implements IPlayer {
|
||||
});
|
||||
}
|
||||
|
||||
private SimpleExoPlayer createPlayer() {
|
||||
private void createPlayer() {
|
||||
DefaultLoadControl.Builder loadControl = new DefaultLoadControl.Builder();
|
||||
loadControl.setBufferDurationsMs(30000, 120000,
|
||||
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
|
||||
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
|
||||
loadControl.setBackBuffer(UserPreferences.getRewindSecs() * 1000 + 500, true);
|
||||
SimpleExoPlayer p = ExoPlayerFactory.newSimpleInstance(context, new DefaultRenderersFactory(context),
|
||||
new DefaultTrackSelector(), loadControl.createDefaultLoadControl());
|
||||
p.setSeekParameters(SeekParameters.EXACT);
|
||||
p.addListener(new Player.EventListener() {
|
||||
trackSelector = new DefaultTrackSelector();
|
||||
exoPlayer = ExoPlayerFactory.newSimpleInstance(context, new DefaultRenderersFactory(context),
|
||||
trackSelector, loadControl.createDefaultLoadControl());
|
||||
exoPlayer.setSeekParameters(SeekParameters.EXACT);
|
||||
exoPlayer.addListener(new Player.EventListener() {
|
||||
@Override
|
||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
||||
if (audioCompletionListener != null && playbackState == Player.STATE_ENDED) {
|
||||
@ -93,7 +104,6 @@ public class ExoPlayerWrapper implements IPlayer {
|
||||
audioSeekCompleteListener.onSeekComplete(null);
|
||||
}
|
||||
});
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -154,7 +164,7 @@ public class ExoPlayerWrapper implements IPlayer {
|
||||
@Override
|
||||
public void reset() {
|
||||
exoPlayer.release();
|
||||
exoPlayer = createPlayer();
|
||||
createPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -226,6 +236,67 @@ public class ExoPlayerWrapper implements IPlayer {
|
||||
exoPlayer.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAudioTracks() {
|
||||
List<String> trackNames = new ArrayList<>();
|
||||
TrackNameProvider trackNameProvider = new DefaultTrackNameProvider(context.getResources());
|
||||
for (Format format : getFormats()) {
|
||||
trackNames.add(trackNameProvider.getTrackName(format));
|
||||
}
|
||||
return trackNames;
|
||||
}
|
||||
|
||||
private List<Format> getFormats() {
|
||||
List<Format> formats = new ArrayList<>();
|
||||
MappingTrackSelector.MappedTrackInfo trackInfo = trackSelector.getCurrentMappedTrackInfo();
|
||||
if (trackInfo == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
TrackGroupArray trackGroups = trackInfo.getTrackGroups(getAudioRendererIndex());
|
||||
for (int i = 0; i < trackGroups.length; i++) {
|
||||
formats.add(trackGroups.get(i).getFormat(0));
|
||||
}
|
||||
return formats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAudioTrack(int track) {
|
||||
MappingTrackSelector.MappedTrackInfo trackInfo = trackSelector.getCurrentMappedTrackInfo();
|
||||
if (trackInfo == null) {
|
||||
return;
|
||||
}
|
||||
TrackGroupArray trackGroups = trackInfo.getTrackGroups(getAudioRendererIndex());
|
||||
DefaultTrackSelector.SelectionOverride override = new DefaultTrackSelector.SelectionOverride(track, 0);
|
||||
DefaultTrackSelector.ParametersBuilder params = trackSelector.buildUponParameters()
|
||||
.setSelectionOverride(getAudioRendererIndex(), trackGroups, override);
|
||||
trackSelector.setParameters(params);
|
||||
}
|
||||
|
||||
private int getAudioRendererIndex() {
|
||||
for (int i = 0; i < exoPlayer.getRendererCount(); i++) {
|
||||
if (exoPlayer.getRendererType(i) == C.TRACK_TYPE_AUDIO) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelectedAudioTrack() {
|
||||
TrackSelectionArray trackSelections = exoPlayer.getCurrentTrackSelections();
|
||||
List<Format> availableFormats = getFormats();
|
||||
for (int i = 0; i < trackSelections.length; i++) {
|
||||
TrackSelection track = trackSelections.get(i);
|
||||
if (track == null) {
|
||||
continue;
|
||||
}
|
||||
if (availableFormats.contains(track.getSelectedFormat())) {
|
||||
return availableFormats.indexOf(track.getSelectedFormat());
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void setOnCompletionListener(MediaPlayer.OnCompletionListener audioCompletionListener) {
|
||||
this.audioCompletionListener = audioCompletionListener;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import org.antennapod.audio.MediaPlayer;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.FutureTask;
|
||||
@ -828,6 +829,18 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
|
||||
media = playable;
|
||||
}
|
||||
|
||||
public List<String> getAudioTracks() {
|
||||
return mediaPlayer.getAudioTracks();
|
||||
}
|
||||
|
||||
public void setAudioTrack(int track) {
|
||||
mediaPlayer.setAudioTrack(track);
|
||||
}
|
||||
|
||||
public int getSelectedAudioTrack() {
|
||||
return mediaPlayer.getSelectedAudioTrack();
|
||||
}
|
||||
|
||||
private void createMediaPlayer() {
|
||||
if (mediaPlayer != null) {
|
||||
mediaPlayer.release();
|
||||
|
@ -42,6 +42,7 @@ import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -1582,6 +1583,26 @@ public class PlaybackService extends MediaBrowserServiceCompat {
|
||||
return mediaPlayer.getPosition();
|
||||
}
|
||||
|
||||
public List<String> getAudioTracks() {
|
||||
if (mediaPlayer == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return mediaPlayer.getAudioTracks();
|
||||
}
|
||||
|
||||
public int getSelectedAudioTrack() {
|
||||
if (mediaPlayer == null) {
|
||||
return -1;
|
||||
}
|
||||
return mediaPlayer.getSelectedAudioTrack();
|
||||
}
|
||||
|
||||
public void setAudioTrack(int track) {
|
||||
if (mediaPlayer != null) {
|
||||
mediaPlayer.setAudioTrack(track);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isStreaming() {
|
||||
return mediaPlayer.isStreaming();
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.SurfaceHolder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.MediaType;
|
||||
@ -230,6 +231,12 @@ public abstract class PlaybackServiceMediaPlayer {
|
||||
|
||||
protected abstract void setPlayable(Playable playable);
|
||||
|
||||
public abstract List<String> getAudioTracks();
|
||||
|
||||
public abstract void setAudioTrack(int track);
|
||||
|
||||
public abstract int getSelectedAudioTrack();
|
||||
|
||||
public void skip() {
|
||||
endPlayback(false, true, true, true);
|
||||
}
|
||||
|
@ -10,45 +10,58 @@ import org.antennapod.audio.MediaPlayer;
|
||||
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class AudioPlayer extends MediaPlayer implements IPlayer {
|
||||
private static final String TAG = "AudioPlayer";
|
||||
private static final String TAG = "AudioPlayer";
|
||||
|
||||
public AudioPlayer(Context context) {
|
||||
super(context);
|
||||
PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.registerOnSharedPreferenceChangeListener(sonicListener);
|
||||
}
|
||||
public AudioPlayer(Context context) {
|
||||
super(context);
|
||||
PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.registerOnSharedPreferenceChangeListener((sharedPreferences, key) -> {
|
||||
if (key.equals(UserPreferences.PREF_MEDIA_PLAYER)) {
|
||||
checkMpi();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private final SharedPreferences.OnSharedPreferenceChangeListener sonicListener =
|
||||
(sharedPreferences, key) -> {
|
||||
if (key.equals(UserPreferences.PREF_MEDIA_PLAYER)) {
|
||||
checkMpi();
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public void setDisplay(SurfaceHolder sh) {
|
||||
if (sh != null) {
|
||||
Log.e(TAG, "Setting display not supported in Audio Player");
|
||||
throw new UnsupportedOperationException("Setting display not supported in Audio Player");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplay(SurfaceHolder sh) {
|
||||
if (sh != null) {
|
||||
Log.e(TAG, "Setting display not supported in Audio Player");
|
||||
throw new UnsupportedOperationException("Setting display not supported in Audio Player");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void setPlaybackParams(float speed, boolean skipSilence) {
|
||||
if (canSetSpeed()) {
|
||||
setPlaybackSpeed(speed);
|
||||
}
|
||||
//Default player does not support silence skipping
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlaybackParams(float speed, boolean skipSilence) {
|
||||
if(canSetSpeed()) {
|
||||
setPlaybackSpeed(speed);
|
||||
}
|
||||
//Default player does not support silence skipping
|
||||
}
|
||||
@Override
|
||||
protected boolean useSonic() {
|
||||
return UserPreferences.useSonic();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean useSonic() {
|
||||
return UserPreferences.useSonic();
|
||||
}
|
||||
@Override
|
||||
protected boolean downmix() {
|
||||
return UserPreferences.stereoToMono();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean downmix() {
|
||||
return UserPreferences.stereoToMono();
|
||||
}
|
||||
public List<String> getAudioTracks() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAudioTrack(int track) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelectedAudioTrack() {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -4,48 +4,54 @@ import android.content.Context;
|
||||
import android.view.SurfaceHolder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public interface IPlayer {
|
||||
|
||||
boolean canSetSpeed();
|
||||
boolean canSetSpeed();
|
||||
|
||||
boolean canDownmix();
|
||||
boolean canDownmix();
|
||||
|
||||
int getCurrentPosition();
|
||||
|
||||
int getCurrentPosition();
|
||||
float getCurrentSpeedMultiplier();
|
||||
|
||||
float getCurrentSpeedMultiplier();
|
||||
int getDuration();
|
||||
|
||||
int getDuration();
|
||||
boolean isPlaying();
|
||||
|
||||
boolean isPlaying();
|
||||
void pause();
|
||||
|
||||
void pause();
|
||||
void prepare() throws IllegalStateException, IOException;
|
||||
|
||||
void prepare() throws IllegalStateException, IOException;
|
||||
void release();
|
||||
|
||||
void release();
|
||||
void reset();
|
||||
|
||||
void reset();
|
||||
void seekTo(int msec);
|
||||
|
||||
void seekTo(int msec);
|
||||
void setAudioStreamType(int streamtype);
|
||||
|
||||
void setAudioStreamType(int streamtype);
|
||||
|
||||
void setDataSource(String path) throws IllegalStateException, IOException,
|
||||
void setDataSource(String path) throws IllegalStateException, IOException,
|
||||
IllegalArgumentException, SecurityException;
|
||||
|
||||
void setDisplay(SurfaceHolder sh);
|
||||
void setDisplay(SurfaceHolder sh);
|
||||
|
||||
void setPlaybackParams(float speed, boolean skipSilence);
|
||||
void setPlaybackParams(float speed, boolean skipSilence);
|
||||
|
||||
void setDownmix(boolean enable);
|
||||
void setDownmix(boolean enable);
|
||||
|
||||
void setVolume(float left, float right);
|
||||
void setVolume(float left, float right);
|
||||
|
||||
void start();
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
void stop();
|
||||
|
||||
void setWakeMode(Context context, int mode);
|
||||
|
||||
List<String> getAudioTracks();
|
||||
|
||||
void setAudioTrack(int track);
|
||||
|
||||
int getSelectedAudioTrack();
|
||||
}
|
||||
|
@ -44,6 +44,9 @@ import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Communicates with the playback service. GUI classes should use this class to
|
||||
* control playback instead of communicating with the PlaybackService directly.
|
||||
@ -627,6 +630,26 @@ public class PlaybackController {
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getAudioTracks() {
|
||||
if (playbackService == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return playbackService.getAudioTracks();
|
||||
}
|
||||
|
||||
public int getSelectedAudioTrack() {
|
||||
if (playbackService == null) {
|
||||
return -1;
|
||||
}
|
||||
return playbackService.getSelectedAudioTrack();
|
||||
}
|
||||
|
||||
public void setAudioTrack(int track) {
|
||||
if (playbackService != null) {
|
||||
playbackService.setAudioTrack(track);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPlayingVideoLocally() {
|
||||
if (PlaybackService.isCasting()) {
|
||||
return false;
|
||||
|
@ -3,37 +3,53 @@ package de.danoeh.antennapod.core.util.playback;
|
||||
import android.media.MediaPlayer;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class VideoPlayer extends MediaPlayer implements IPlayer {
|
||||
private static final String TAG = "VideoPlayer";
|
||||
private static final String TAG = "VideoPlayer";
|
||||
|
||||
@Override
|
||||
public boolean canSetSpeed() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean canSetSpeed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDownmix() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean canDownmix() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getCurrentSpeedMultiplier() {
|
||||
return 1;
|
||||
}
|
||||
@Override
|
||||
public float getCurrentSpeedMultiplier() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlaybackParams(float speed, boolean skipSilence) {
|
||||
//Ignore this for non ExoPlayer implementations
|
||||
}
|
||||
@Override
|
||||
public void setPlaybackParams(float speed, boolean skipSilence) {
|
||||
//Ignore this for non ExoPlayer implementations
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDownmix(boolean b) {
|
||||
Log.e(TAG, "Setting downmix unsupported in video player");
|
||||
throw new UnsupportedOperationException("Setting downmix unsupported in video player");
|
||||
}
|
||||
@Override
|
||||
public void setDownmix(boolean b) {
|
||||
Log.e(TAG, "Setting downmix unsupported in video player");
|
||||
throw new UnsupportedOperationException("Setting downmix unsupported in video player");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVideoScalingMode(int mode) {
|
||||
super.setVideoScalingMode(mode);
|
||||
}
|
||||
|
||||
public List<String> getAudioTracks() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAudioTrack(int track) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelectedAudioTrack() {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,9 @@ import com.google.android.libraries.cast.companionlibrary.cast.exceptions.NoConn
|
||||
import com.google.android.libraries.cast.companionlibrary.cast.exceptions.TransientNetworkDisconnectionException;
|
||||
|
||||
import de.danoeh.antennapod.core.cast.MediaInfoCreator;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@ -602,6 +605,19 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAudioTracks() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public void setAudioTrack(int track) {
|
||||
|
||||
}
|
||||
|
||||
public int getSelectedAudioTrack() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Future<?> endPlayback(boolean hasEnded, boolean wasSkipped, boolean shouldContinue,
|
||||
boolean toStoppedState) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user