diff --git a/app/build.gradle b/app/build.gradle
index f2f467326..a1da6a7f0 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -42,10 +42,10 @@ dependencies {
compile 'de.hdodenhof:circleimageview:2.0.0'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
compile 'com.github.nirhart:parallaxscroll:1.0'
- compile 'com.google.android.exoplayer:exoplayer:r1.5.5'
compile 'com.google.code.gson:gson:2.4'
compile 'com.nononsenseapps:filepicker:3.0.0'
compile 'ch.acra:acra:4.9.0'
+ compile 'com.devbrackets.android:exomedia:3.1.1'
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
testCompile 'org.json:json:20160810'
diff --git a/app/src/main/java/org/schabi/newpipe/player/ExoPlayerActivity.java b/app/src/main/java/org/schabi/newpipe/player/ExoPlayerActivity.java
index c38e63545..7fe97d0dc 100644
--- a/app/src/main/java/org/schabi/newpipe/player/ExoPlayerActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/player/ExoPlayerActivity.java
@@ -16,549 +16,240 @@
/**
* Extended by Christian Schabesberger on 24.12.15.
- *
+ *
* Copyright (C) Christian Schabesberger 2015
* ExoPlayerActivity.java is part of NewPipe. all changes are under GPL3
- *
+ *
* NewPipe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* NewPipe is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with NewPipe. If not, see .
*/
package org.schabi.newpipe.player;
-import org.schabi.newpipe.R;
-import org.schabi.newpipe.player.exoplayer.DashRendererBuilder;
-import org.schabi.newpipe.player.exoplayer.EventLogger;
-import org.schabi.newpipe.player.exoplayer.ExtractorRendererBuilder;
-import org.schabi.newpipe.player.exoplayer.HlsRendererBuilder;
-import org.schabi.newpipe.player.exoplayer.NPExoPlayer;
-import org.schabi.newpipe.player.exoplayer.NPExoPlayer.RendererBuilder;
-import org.schabi.newpipe.player.exoplayer.SmoothStreamingRendererBuilder;
-
-import com.google.android.exoplayer.AspectRatioFrameLayout;
-import com.google.android.exoplayer.ExoPlaybackException;
-import com.google.android.exoplayer.ExoPlayer;
-import com.google.android.exoplayer.MediaCodecTrackRenderer.DecoderInitializationException;
-import com.google.android.exoplayer.MediaCodecUtil.DecoderQueryException;
-import com.google.android.exoplayer.MediaFormat;
-import com.google.android.exoplayer.audio.AudioCapabilities;
-import com.google.android.exoplayer.audio.AudioCapabilitiesReceiver;
-import com.google.android.exoplayer.drm.UnsupportedDrmException;
-import com.google.android.exoplayer.metadata.GeobMetadata;
-import com.google.android.exoplayer.metadata.PrivMetadata;
-import com.google.android.exoplayer.metadata.TxxxMetadata;
-import com.google.android.exoplayer.text.CaptionStyleCompat;
-import com.google.android.exoplayer.text.Cue;
-import com.google.android.exoplayer.text.SubtitleLayout;
-import com.google.android.exoplayer.util.DebugTextViewHelper;
-import com.google.android.exoplayer.util.MimeTypes;
-import com.google.android.exoplayer.util.Util;
-import com.google.android.exoplayer.util.VerboseLogUtil;
-
-import android.Manifest.permission;
-import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.net.Uri;
import android.os.Bundle;
-import android.text.TextUtils;
import android.util.Log;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
import android.view.View;
-import android.view.View.OnKeyListener;
-import android.view.View.OnTouchListener;
-import android.view.accessibility.CaptioningManager;
-import android.widget.MediaController;
-import android.widget.PopupMenu;
-import android.widget.PopupMenu.OnMenuItemClickListener;
-import android.widget.Toast;
+import android.view.WindowManager;
+import android.widget.ImageButton;
+import android.widget.SeekBar;
-import java.net.CookieHandler;
-import java.net.CookieManager;
-import java.net.CookiePolicy;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import com.devbrackets.android.exomedia.listener.OnCompletionListener;
+import com.devbrackets.android.exomedia.listener.OnPreparedListener;
+import com.devbrackets.android.exomedia.listener.VideoControlsVisibilityListener;
+import com.devbrackets.android.exomedia.ui.widget.EMVideoView;
+import com.devbrackets.android.exomedia.ui.widget.VideoControlsMobile;
-/**
- * An activity that plays media using {@link NPExoPlayer}.
- */
-public class ExoPlayerActivity extends Activity {
+import org.schabi.newpipe.R;
- // For use within demo app code.
- public static final String CONTENT_ID_EXTRA = "content_id";
- public static final String CONTENT_TYPE_EXTRA = "content_type";
- public static final String PROVIDER_EXTRA = "provider";
+public class ExoPlayerActivity extends Activity implements OnPreparedListener, OnCompletionListener {
+ private static final String TAG = "ExoPlayerActivity";
+ private EMVideoView videoView;
+ private CustomVideoControls videoControls;
- // For use when launching the demo app using adb.
- private static final String CONTENT_EXT_EXTRA = "type";
-
- private static final String TAG = "PlayerActivity";
- private static final int MENU_GROUP_TRACKS = 1;
- private static final int ID_OFFSET = 2;
-
- private static final CookieManager defaultCookieManager;
- static {
- defaultCookieManager = new CookieManager();
- defaultCookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
- }
-
- private EventLogger eventLogger;
- private MediaController mediaController;
- private View shutterView;
- private AspectRatioFrameLayout videoFrame;
- private SurfaceView surfaceView;
- private SubtitleLayout subtitleLayout;
-
- private NPExoPlayer player;
- private boolean playerNeedsPrepare;
-
- private long playerPosition;
- private boolean enableBackgroundAudio = true;
-
- private Uri contentUri;
- private int contentType;
- private String contentId;
- private String provider;
-
- private AudioCapabilitiesReceiver audioCapabilitiesReceiver;
-
-
- NPExoPlayer.Listener exoPlayerListener = new NPExoPlayer.Listener() {
- @Override
- public void onStateChanged(boolean playWhenReady, int playbackState) {
- if (playbackState == ExoPlayer.STATE_ENDED) {
- showControls();
- }
- String text = "playWhenReady=" + playWhenReady + ", playbackState=";
- switch(playbackState) {
- case ExoPlayer.STATE_BUFFERING:
- text += "buffering";
- break;
- case ExoPlayer.STATE_ENDED:
- text += "ended";
- break;
- case ExoPlayer.STATE_IDLE:
- text += "idle";
- break;
- case ExoPlayer.STATE_PREPARING:
- text += "preparing";
- break;
- case ExoPlayer.STATE_READY:
- text += "ready";
- break;
- default:
- text += "unknown";
- break;
- }
- //todo: put text in some log
- }
-
- @Override
- public void onError(Exception e) {
- String errorString = null;
- if (e instanceof UnsupportedDrmException) {
- // Special case DRM failures.
- UnsupportedDrmException unsupportedDrmException = (UnsupportedDrmException) e;
- errorString = getString(Util.SDK_INT < 18 ? R.string.error_drm_not_supported
- : unsupportedDrmException.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME
- ? R.string.error_drm_unsupported_scheme : R.string.error_drm_unknown);
- } else if (e instanceof ExoPlaybackException
- && e.getCause() instanceof DecoderInitializationException) {
- // Special case for decoder initialization failures.
- DecoderInitializationException decoderInitializationException =
- (DecoderInitializationException) e.getCause();
- if (decoderInitializationException.decoderName == null) {
- if (decoderInitializationException.getCause() instanceof DecoderQueryException) {
- errorString = getString(R.string.error_querying_decoders);
- } else if (decoderInitializationException.secureDecoderRequired) {
- errorString = getString(R.string.error_no_secure_decoder,
- decoderInitializationException.mimeType);
- } else {
- errorString = getString(R.string.error_no_decoder,
- decoderInitializationException.mimeType);
- }
- } else {
- errorString = getString(R.string.error_instantiating_decoder,
- decoderInitializationException.decoderName);
- }
- }
- if (errorString != null) {
- Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_LONG).show();
- }
- playerNeedsPrepare = true;
- showControls();
- }
-
- @Override
- public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthAspectRatio) {
- shutterView.setVisibility(View.GONE);
- videoFrame.setAspectRatio(
- height == 0 ? 1 : (width * pixelWidthAspectRatio) / height);
- }
- };
-
- SurfaceHolder.Callback surfaceHolderCallback = new SurfaceHolder.Callback() {
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- if (player != null) {
- player.setSurface(holder.getSurface());
- }
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- // Do nothing.
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- if (player != null) {
- player.blockingClearSurface();
- }
- }
- };
-
- NPExoPlayer.CaptionListener captionListener = new NPExoPlayer.CaptionListener() {
- @Override
- public void onCues(List cues) {
- subtitleLayout.setCues(cues);
- }
- };
-
- NPExoPlayer.Id3MetadataListener id3MetadataListener = new NPExoPlayer.Id3MetadataListener() {
- @Override
- public void onId3Metadata(Map metadata) {
- for (Map.Entry entry : metadata.entrySet()) {
- if (TxxxMetadata.TYPE.equals(entry.getKey())) {
- TxxxMetadata txxxMetadata = (TxxxMetadata) entry.getValue();
- Log.i(TAG, String.format("ID3 TimedMetadata %s: description=%s, value=%s",
- TxxxMetadata.TYPE, txxxMetadata.description, txxxMetadata.value));
- } else if (PrivMetadata.TYPE.equals(entry.getKey())) {
- PrivMetadata privMetadata = (PrivMetadata) entry.getValue();
- Log.i(TAG, String.format("ID3 TimedMetadata %s: owner=%s",
- PrivMetadata.TYPE, privMetadata.owner));
- } else if (GeobMetadata.TYPE.equals(entry.getKey())) {
- GeobMetadata geobMetadata = (GeobMetadata) entry.getValue();
- Log.i(TAG, String.format("ID3 TimedMetadata %s: mimeType=%s, filename=%s, description=%s",
- GeobMetadata.TYPE, geobMetadata.mimeType, geobMetadata.filename,
- geobMetadata.description));
- } else {
- Log.i(TAG, String.format("ID3 TimedMetadata %s", entry.getKey()));
- }
- }
- }
- };
-
- AudioCapabilitiesReceiver.Listener audioCapabilitiesListener = new AudioCapabilitiesReceiver.Listener() {
- @Override
- public void onAudioCapabilitiesChanged(AudioCapabilities audioCapabilities) {
- if (player == null) {
- return;
- }
- boolean backgrounded = player.getBackgrounded();
- boolean playWhenReady = player.getPlayWhenReady();
- releasePlayer();
- preparePlayer(playWhenReady);
- player.setBackgrounded(backgrounded);
- }
- };
-
- // Activity lifecycle
+ public static final String VIDEO_TITLE = "video_title";
+ public static final String CHANNEL_NAME = "channel_name";
+ private String videoTitle = "";
+ private volatile String channelName = "";
+ private int lastPosition;
+ private boolean isFinished;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
- setContentView(R.layout.exo_player_activity);
- View root = findViewById(R.id.root);
- root.setOnTouchListener(new OnTouchListener() {
- @Override
- public boolean onTouch(View view, MotionEvent motionEvent) {
- if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
- toggleControlsVisibility();
- } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
- view.performClick();
- }
- return true;
- }
- });
- root.setOnKeyListener(new OnKeyListener() {
- @Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE
- || keyCode == KeyEvent.KEYCODE_MENU) {
- return false;
- }
- return mediaController.dispatchKeyEvent(event);
- }
- });
-
- shutterView = findViewById(R.id.shutter);
-
- videoFrame = (AspectRatioFrameLayout) findViewById(R.id.video_frame);
- surfaceView = (SurfaceView) findViewById(R.id.surface_view);
- surfaceView.getHolder().addCallback(surfaceHolderCallback);
- subtitleLayout = (SubtitleLayout) findViewById(R.id.subtitles);
-
- //todo: replace that creapy mediaController
- mediaController = new KeyCompatibleMediaController(this);
- mediaController.setAnchorView(root);
-
- //todo: check what cookie handler does, and if we even need it
- CookieHandler currentHandler = CookieHandler.getDefault();
- if (currentHandler != defaultCookieManager) {
- CookieHandler.setDefault(defaultCookieManager);
- }
-
- audioCapabilitiesReceiver = new AudioCapabilitiesReceiver(this, audioCapabilitiesListener);
- audioCapabilitiesReceiver.register();
+ setContentView(R.layout.activity_exo_player);
+ videoView = (EMVideoView) findViewById(R.id.emVideoView);
}
@Override
- public void onNewIntent(Intent intent) {
- releasePlayer();
- playerPosition = 0;
- setIntent(intent);
- }
-
- @Override
- public void onResume() {
- super.onResume();
+ protected void onStart() {
+ super.onStart();
Intent intent = getIntent();
- contentUri = intent.getData();
- contentType = intent.getIntExtra(CONTENT_TYPE_EXTRA,
- inferContentType(contentUri, intent.getStringExtra(CONTENT_EXT_EXTRA)));
- contentId = intent.getStringExtra(CONTENT_ID_EXTRA);
- provider = intent.getStringExtra(PROVIDER_EXTRA);
- configureSubtitleView();
- if (player == null) {
- if (!maybeRequestPermission()) {
- preparePlayer(true);
+ videoTitle = intent.getStringExtra(VIDEO_TITLE);
+ channelName = intent.getStringExtra(CHANNEL_NAME);
+ videoView.setOnPreparedListener(this);
+ videoView.setOnCompletionListener(this);
+ videoView.setVideoURI(intent.getData());
+
+ videoControls = new CustomVideoControls(this);
+ videoControls.setTitle(videoTitle);
+ videoControls.setSubTitle(channelName);
+
+ //We don't need these button until the playlist or queue is implemented
+ videoControls.setNextButtonRemoved(true);
+ videoControls.setPreviousButtonRemoved(true);
+
+ videoControls.setVisibilityListener(new VideoControlsVisibilityListener() {
+ @Override
+ public void onControlsShown() {
+ Log.d(TAG, "------------ onControlsShown() called");
+ showSystemUi();
}
- } else {
- player.setBackgrounded(false);
- }
+
+ @Override
+ public void onControlsHidden() {
+ Log.d(TAG, "------------ onControlsHidden() called");
+ hideSystemUi();
+ }
+ });
+ videoView.setControls(videoControls);
}
@Override
- public void onPause() {
+ public void onPrepared() {
+ Log.d(TAG, "onPrepared() called");
+ videoView.start();
+ }
+
+ @Override
+ public void onCompletion() {
+ Log.d(TAG, "onCompletion() called");
+// videoView.getVideoControls().setButtonListener();
+ //videoView.restart();
+ videoControls.setRewindButtonRemoved(true);
+ videoControls.setFastForwardButtonRemoved(true);
+ isFinished = true;
+ videoControls.getSeekBar().setEnabled(false);
+ }
+
+ @Override
+ protected void onPause() {
super.onPause();
- if (!enableBackgroundAudio) {
- releasePlayer();
- } else {
- player.setBackgrounded(true);
- }
- shutterView.setVisibility(View.VISIBLE);
+ videoView.stopPlayback();
+ lastPosition = videoView.getCurrentPosition();
}
@Override
- public void onDestroy() {
+ protected void onResume() {
+ super.onResume();
+ if (lastPosition > 0) videoView.seekTo(lastPosition);
+ }
+
+ @Override
+ protected void onDestroy() {
super.onDestroy();
- audioCapabilitiesReceiver.unregister();
- releasePlayer();
+ videoView.stopPlayback();
}
+ private void showSystemUi() {
+ Log.d(TAG, "showSystemUi() called");
+ getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ getWindow().getDecorView().setSystemUiVisibility(0);
+ }
- // Permission request listener method
-
- @Override
- public void onRequestPermissionsResult(int requestCode, String[] permissions,
- int[] grantResults) {
- if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- preparePlayer(true);
- } else {
- Toast.makeText(getApplicationContext(), R.string.storage_permission_denied,
- Toast.LENGTH_LONG).show();
- finish();
+ private void hideSystemUi() {
+ Log.d(TAG, "hideSystemUi() called");
+ if (android.os.Build.VERSION.SDK_INT >= 17) {
+ getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_IMMERSIVE
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
+ getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
- // Permission management methods
+ private class CustomVideoControls extends VideoControlsMobile {
+ protected static final int FAST_FORWARD_REWIND_AMOUNT = 8000;
- /**
- * Checks whether it is necessary to ask for permission to read storage. If necessary, it also
- * requests permission.
- *
- * @return true if a permission request is made. False if it is not necessary.
- */
- @TargetApi(23)
- private boolean maybeRequestPermission() {
- if (requiresPermission(contentUri)) {
- requestPermissions(new String[] {permission.READ_EXTERNAL_STORAGE}, 0);
- return true;
- } else {
- return false;
- }
- }
+ protected ImageButton fastForwardButton;
+ protected ImageButton rewindButton;
- @TargetApi(23)
- private boolean requiresPermission(Uri uri) {
- return Util.SDK_INT >= 23
- && Util.isLocalFileUri(uri)
- && checkSelfPermission(permission.READ_EXTERNAL_STORAGE)
- != PackageManager.PERMISSION_GRANTED;
- }
-
- // Internal methods
-
- private RendererBuilder getRendererBuilder() {
- String userAgent = Util.getUserAgent(this, "NewPipeExoPlayer");
- switch (contentType) {
- case Util.TYPE_SS:
- // default
- //return new SmoothStreamingRendererBuilder(this, userAgent, contentUri.toString());
- case Util.TYPE_DASH:
- // if a dash manifest is available
- //return new DashRendererBuilder(this, userAgent, contentUri.toString());
- case Util.TYPE_HLS:
- // for livestreams
- return new HlsRendererBuilder(this, userAgent, contentUri.toString());
- case Util.TYPE_OTHER:
- // video only streaming
- return new ExtractorRendererBuilder(this, userAgent, contentUri);
- default:
- throw new IllegalStateException("Unsupported type: " + contentType);
- }
- }
-
- private void preparePlayer(boolean playWhenReady) {
- if (player == null) {
- player = new NPExoPlayer(getRendererBuilder());
- player.addListener(exoPlayerListener);
- player.setCaptionListener(captionListener);
- player.setMetadataListener(id3MetadataListener);
- player.seekTo(playerPosition);
- playerNeedsPrepare = true;
- mediaController.setMediaPlayer(player.getPlayerControl());
- mediaController.setEnabled(true);
- eventLogger = new EventLogger();
- eventLogger.startSession();
- player.addListener(eventLogger);
- player.setInfoListener(eventLogger);
- player.setInternalErrorListener(eventLogger);
- }
- if (playerNeedsPrepare) {
- player.prepare();
- playerNeedsPrepare = false;
- }
- player.setSurface(surfaceView.getHolder().getSurface());
- player.setPlayWhenReady(playWhenReady);
- }
-
- private void releasePlayer() {
- if (player != null) {
- playerPosition = player.getCurrentPosition();
- player.release();
- player = null;
- eventLogger.endSession();
- eventLogger = null;
- }
- }
-
- private void toggleControlsVisibility() {
- if (mediaController.isShowing()) {
- mediaController.hide();
- } else {
- showControls();
- }
- }
-
- private void showControls() {
- mediaController.show(0);
- }
-
- private void configureSubtitleView() {
- CaptionStyleCompat style;
- float fontScale;
- if (Util.SDK_INT >= 19) {
- style = getUserCaptionStyleV19();
- fontScale = getUserCaptionFontScaleV19();
- } else {
- style = CaptionStyleCompat.DEFAULT;
- fontScale = 1.0f;
- }
- subtitleLayout.setStyle(style);
- subtitleLayout.setFractionalTextSize(SubtitleLayout.DEFAULT_TEXT_SIZE_FRACTION * fontScale);
- }
-
- @TargetApi(19)
- private float getUserCaptionFontScaleV19() {
- CaptioningManager captioningManager =
- (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE);
- return captioningManager.getFontScale();
- }
-
- @TargetApi(19)
- private CaptionStyleCompat getUserCaptionStyleV19() {
- CaptioningManager captioningManager =
- (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE);
- return CaptionStyleCompat.createFromCaptionStyle(captioningManager.getUserStyle());
- }
-
- /**
- * Makes a best guess to infer the type from a media {@link Uri} and an optional overriding file
- * extension.
- *
- * @param uri The {@link Uri} of the media.
- * @param fileExtension An overriding file extension.
- * @return The inferred type.
- */
- private static int inferContentType(Uri uri, String fileExtension) {
- String lastPathSegment = !TextUtils.isEmpty(fileExtension) ? "." + fileExtension
- : uri.getLastPathSegment();
- return Util.inferContentType(lastPathSegment);
- }
-
- private static final class KeyCompatibleMediaController extends MediaController {
-
- private MediaController.MediaPlayerControl playerControl;
-
- public KeyCompatibleMediaController(Context context) {
+ public CustomVideoControls(Context context) {
super(context);
}
@Override
- public void setMediaPlayer(MediaController.MediaPlayerControl playerControl) {
- super.setMediaPlayer(playerControl);
- this.playerControl = playerControl;
+ protected int getLayoutResource() {
+ return R.layout.exomedia_custom_controls;
}
@Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- int keyCode = event.getKeyCode();
- if (playerControl.canSeekForward() && keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) {
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- playerControl.seekTo(playerControl.getCurrentPosition() + 15000); // milliseconds
- show();
+ protected void retrieveViews() {
+ super.retrieveViews();
+ rewindButton = (ImageButton) findViewById(R.id.exomedia_controls_frewind_btn);
+ fastForwardButton = (ImageButton) findViewById(R.id.exomedia_controls_fforward_btn);
+ }
+
+ @Override
+ protected void registerListeners() {
+ super.registerListeners();
+ rewindButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onRewindClicked();
}
- return true;
- } else if (playerControl.canSeekBackward() && keyCode == KeyEvent.KEYCODE_MEDIA_REWIND) {
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- playerControl.seekTo(playerControl.getCurrentPosition() - 5000); // milliseconds
- show();
+ });
+ fastForwardButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onFastForwardClicked();
}
- return true;
+ });
+ }
+
+ public boolean onFastForwardClicked() {
+ if (videoView == null) return false;
+
+ int newPosition = videoView.getCurrentPosition() + FAST_FORWARD_REWIND_AMOUNT;
+ if (newPosition > seekBar.getMax()) newPosition = seekBar.getMax();
+
+ performSeek(newPosition);
+ return true;
+ }
+
+ public boolean onRewindClicked() {
+ if (videoView == null) return false;
+
+ int newPosition = videoView.getCurrentPosition() - FAST_FORWARD_REWIND_AMOUNT;
+ if (newPosition < 0) newPosition = 0;
+
+ performSeek(newPosition);
+ return true;
+ }
+
+ @Override
+ public void setFastForwardButtonRemoved(boolean removed) {
+ fastForwardButton.setVisibility(removed ? View.GONE : View.VISIBLE);
+ }
+
+ @Override
+ public void setRewindButtonRemoved(boolean removed) {
+ rewindButton.setVisibility(removed ? View.GONE : View.VISIBLE);
+ }
+
+ @Override
+ protected void onPlayPauseClick() {
+ super.onPlayPauseClick();
+ if (videoView == null) return;
+ Log.d(TAG, "onPlayPauseClick() called" + videoView.getDuration()+" position= "+ videoView.getCurrentPosition());
+ if (isFinished) {
+ videoView.restart();
+ setRewindButtonRemoved(false);
+ setFastForwardButtonRemoved(false);
+ isFinished = false;
+ seekBar.setEnabled(true);
}
- return super.dispatchKeyEvent(event);
+ }
+
+ private void performSeek(int newPosition) {
+ internalListener.onSeekEnded(newPosition);
+ }
+
+ public SeekBar getSeekBar() {
+ return seekBar;
}
}
-
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/exoplayer/DashRendererBuilder.java b/app/src/main/java/org/schabi/newpipe/player/exoplayer/DashRendererBuilder.java
deleted file mode 100644
index f12dc8975..000000000
--- a/app/src/main/java/org/schabi/newpipe/player/exoplayer/DashRendererBuilder.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.schabi.newpipe.player.exoplayer;
-
-import org.schabi.newpipe.player.exoplayer.NPExoPlayer.RendererBuilder;
-
-import com.google.android.exoplayer.DefaultLoadControl;
-import com.google.android.exoplayer.LoadControl;
-import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
-import com.google.android.exoplayer.MediaCodecSelector;
-import com.google.android.exoplayer.MediaCodecVideoTrackRenderer;
-import com.google.android.exoplayer.TrackRenderer;
-import com.google.android.exoplayer.audio.AudioCapabilities;
-import com.google.android.exoplayer.chunk.ChunkSampleSource;
-import com.google.android.exoplayer.chunk.ChunkSource;
-import com.google.android.exoplayer.chunk.FormatEvaluator.AdaptiveEvaluator;
-import com.google.android.exoplayer.dash.DashChunkSource;
-import com.google.android.exoplayer.dash.DefaultDashTrackSelector;
-import com.google.android.exoplayer.dash.mpd.AdaptationSet;
-import com.google.android.exoplayer.dash.mpd.MediaPresentationDescription;
-import com.google.android.exoplayer.dash.mpd.MediaPresentationDescriptionParser;
-import com.google.android.exoplayer.dash.mpd.Period;
-import com.google.android.exoplayer.dash.mpd.UtcTimingElement;
-import com.google.android.exoplayer.dash.mpd.UtcTimingElementResolver;
-import com.google.android.exoplayer.dash.mpd.UtcTimingElementResolver.UtcTimingCallback;
-import com.google.android.exoplayer.drm.MediaDrmCallback;
-import com.google.android.exoplayer.drm.StreamingDrmSessionManager;
-import com.google.android.exoplayer.drm.UnsupportedDrmException;
-import com.google.android.exoplayer.text.TextTrackRenderer;
-import com.google.android.exoplayer.upstream.DataSource;
-import com.google.android.exoplayer.upstream.DefaultAllocator;
-import com.google.android.exoplayer.upstream.DefaultBandwidthMeter;
-import com.google.android.exoplayer.upstream.DefaultUriDataSource;
-import com.google.android.exoplayer.upstream.UriDataSource;
-import com.google.android.exoplayer.util.ManifestFetcher;
-import com.google.android.exoplayer.util.Util;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.media.MediaCodec;
-import android.os.Handler;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * A {@link RendererBuilder} for DASH.
- */
-public class DashRendererBuilder implements RendererBuilder {
-
- private static final String TAG = "DashRendererBuilder";
-
- private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
- private static final int VIDEO_BUFFER_SEGMENTS = 200;
- private static final int AUDIO_BUFFER_SEGMENTS = 54;
- private static final int TEXT_BUFFER_SEGMENTS = 2;
- private static final int LIVE_EDGE_LATENCY_MS = 30000;
-
- private static final int SECURITY_LEVEL_UNKNOWN = -1;
- private static final int SECURITY_LEVEL_1 = 1;
- private static final int SECURITY_LEVEL_3 = 3;
-
- private final Context context;
- private final String userAgent;
- private final String url;
- private final MediaDrmCallback drmCallback;
-
- private AsyncRendererBuilder currentAsyncBuilder;
-
- public DashRendererBuilder(Context context, String userAgent, String url,
- MediaDrmCallback drmCallback) {
- this.context = context;
- this.userAgent = userAgent;
- this.url = url;
- this.drmCallback = drmCallback;
- }
-
- @Override
- public void buildRenderers(NPExoPlayer player) {
- currentAsyncBuilder = new AsyncRendererBuilder(context, userAgent, url, drmCallback, player);
- currentAsyncBuilder.init();
- }
-
- @Override
- public void cancel() {
- if (currentAsyncBuilder != null) {
- currentAsyncBuilder.cancel();
- currentAsyncBuilder = null;
- }
- }
-
- private static final class AsyncRendererBuilder
- implements ManifestFetcher.ManifestCallback, UtcTimingCallback {
-
- private final Context context;
- private final String userAgent;
- private final MediaDrmCallback drmCallback;
- private final NPExoPlayer player;
- private final ManifestFetcher manifestFetcher;
- private final UriDataSource manifestDataSource;
-
- private boolean canceled;
- private MediaPresentationDescription manifest;
- private long elapsedRealtimeOffset;
-
- public AsyncRendererBuilder(Context context, String userAgent, String url,
- MediaDrmCallback drmCallback, NPExoPlayer player) {
- this.context = context;
- this.userAgent = userAgent;
- this.drmCallback = drmCallback;
- this.player = player;
- MediaPresentationDescriptionParser parser = new MediaPresentationDescriptionParser();
- manifestDataSource = new DefaultUriDataSource(context, userAgent);
- manifestFetcher = new ManifestFetcher<>(url, manifestDataSource, parser);
- }
-
- public void init() {
- manifestFetcher.singleLoad(player.getMainHandler().getLooper(), this);
- }
-
- public void cancel() {
- canceled = true;
- }
-
- @Override
- public void onSingleManifest(MediaPresentationDescription manifest) {
- if (canceled) {
- return;
- }
-
- this.manifest = manifest;
- if (manifest.dynamic && manifest.utcTiming != null) {
- UtcTimingElementResolver.resolveTimingElement(manifestDataSource, manifest.utcTiming,
- manifestFetcher.getManifestLoadCompleteTimestamp(), this);
- } else {
- buildRenderers();
- }
- }
-
- @Override
- public void onSingleManifestError(IOException e) {
- if (canceled) {
- return;
- }
-
- player.onRenderersError(e);
- }
-
- @Override
- public void onTimestampResolved(UtcTimingElement utcTiming, long elapsedRealtimeOffset) {
- if (canceled) {
- return;
- }
-
- this.elapsedRealtimeOffset = elapsedRealtimeOffset;
- buildRenderers();
- }
-
- @Override
- public void onTimestampError(UtcTimingElement utcTiming, IOException e) {
- if (canceled) {
- return;
- }
-
- Log.e(TAG, "Failed to resolve UtcTiming element [" + utcTiming + "]", e);
- // Be optimistic and continue in the hope that the device clock is correct.
- buildRenderers();
- }
-
- private void buildRenderers() {
- Period period = manifest.getPeriod(0);
- Handler mainHandler = player.getMainHandler();
- LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SEGMENT_SIZE));
- DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(mainHandler, player);
-
- boolean hasContentProtection = false;
- for (int i = 0; i < period.adaptationSets.size(); i++) {
- AdaptationSet adaptationSet = period.adaptationSets.get(i);
- if (adaptationSet.type != AdaptationSet.TYPE_UNKNOWN) {
- hasContentProtection |= adaptationSet.hasContentProtection();
- }
- }
-
- // Check drm support if necessary.
- boolean filterHdContent = false;
- StreamingDrmSessionManager drmSessionManager = null;
- if (hasContentProtection) {
- if (Util.SDK_INT < 18) {
- player.onRenderersError(
- new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME));
- return;
- }
- try {
- drmSessionManager = StreamingDrmSessionManager.newWidevineInstance(
- player.getPlaybackLooper(), drmCallback, null, player.getMainHandler(), player);
- filterHdContent = getWidevineSecurityLevel(drmSessionManager) != SECURITY_LEVEL_1;
- } catch (UnsupportedDrmException e) {
- player.onRenderersError(e);
- return;
- }
- }
-
- // Build the video renderer.
- DataSource videoDataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
- ChunkSource videoChunkSource = new DashChunkSource(manifestFetcher,
- DefaultDashTrackSelector.newVideoInstance(context, true, filterHdContent),
- videoDataSource, new AdaptiveEvaluator(bandwidthMeter), LIVE_EDGE_LATENCY_MS,
- elapsedRealtimeOffset, mainHandler, player, NPExoPlayer.TYPE_VIDEO);
- ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl,
- VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
- NPExoPlayer.TYPE_VIDEO);
- TrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context, videoSampleSource,
- MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
- drmSessionManager, true, mainHandler, player, 50);
-
- // Build the audio renderer.
- DataSource audioDataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
- ChunkSource audioChunkSource = new DashChunkSource(manifestFetcher,
- DefaultDashTrackSelector.newAudioInstance(), audioDataSource, null, LIVE_EDGE_LATENCY_MS,
- elapsedRealtimeOffset, mainHandler, player, NPExoPlayer.TYPE_AUDIO);
- ChunkSampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl,
- AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
- NPExoPlayer.TYPE_AUDIO);
- TrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(audioSampleSource,
- MediaCodecSelector.DEFAULT, drmSessionManager, true, mainHandler, player,
- AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC);
-
- // Build the text renderer.
- DataSource textDataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
- ChunkSource textChunkSource = new DashChunkSource(manifestFetcher,
- DefaultDashTrackSelector.newTextInstance(), textDataSource, null, LIVE_EDGE_LATENCY_MS,
- elapsedRealtimeOffset, mainHandler, player, NPExoPlayer.TYPE_TEXT);
- ChunkSampleSource textSampleSource = new ChunkSampleSource(textChunkSource, loadControl,
- TEXT_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
- NPExoPlayer.TYPE_TEXT);
- TrackRenderer textRenderer = new TextTrackRenderer(textSampleSource, player,
- mainHandler.getLooper());
-
- // Invoke the callback.
- TrackRenderer[] renderers = new TrackRenderer[NPExoPlayer.RENDERER_COUNT];
- renderers[NPExoPlayer.TYPE_VIDEO] = videoRenderer;
- renderers[NPExoPlayer.TYPE_AUDIO] = audioRenderer;
- renderers[NPExoPlayer.TYPE_TEXT] = textRenderer;
- player.onRenderers(renderers, bandwidthMeter);
- }
-
- private static int getWidevineSecurityLevel(StreamingDrmSessionManager sessionManager) {
- String securityLevelProperty = sessionManager.getPropertyString("securityLevel");
- return securityLevelProperty.equals("L1") ? SECURITY_LEVEL_1 : securityLevelProperty
- .equals("L3") ? SECURITY_LEVEL_3 : SECURITY_LEVEL_UNKNOWN;
- }
-
- }
-
-}
diff --git a/app/src/main/java/org/schabi/newpipe/player/exoplayer/EventLogger.java b/app/src/main/java/org/schabi/newpipe/player/exoplayer/EventLogger.java
deleted file mode 100644
index 62553ab3b..000000000
--- a/app/src/main/java/org/schabi/newpipe/player/exoplayer/EventLogger.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.schabi.newpipe.player.exoplayer;
-
-import com.google.android.exoplayer.ExoPlayer;
-import com.google.android.exoplayer.MediaCodecTrackRenderer.DecoderInitializationException;
-import com.google.android.exoplayer.TimeRange;
-import com.google.android.exoplayer.audio.AudioTrack;
-import com.google.android.exoplayer.chunk.Format;
-import com.google.android.exoplayer.util.VerboseLogUtil;
-
-import android.media.MediaCodec.CryptoException;
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.io.IOException;
-import java.text.NumberFormat;
-import java.util.Locale;
-
-/**
- * Logs player events using {@link Log}.
- */
-public class EventLogger implements NPExoPlayer.Listener, NPExoPlayer.InfoListener,
- NPExoPlayer.InternalErrorListener {
-
- private static final String TAG = "EventLogger";
- private static final NumberFormat TIME_FORMAT;
- static {
- TIME_FORMAT = NumberFormat.getInstance(Locale.US);
- TIME_FORMAT.setMinimumFractionDigits(2);
- TIME_FORMAT.setMaximumFractionDigits(2);
- }
-
- private long sessionStartTimeMs;
- private long[] loadStartTimeMs;
- private long[] availableRangeValuesUs;
-
- public EventLogger() {
- loadStartTimeMs = new long[NPExoPlayer.RENDERER_COUNT];
- }
-
- public void startSession() {
- sessionStartTimeMs = SystemClock.elapsedRealtime();
- Log.d(TAG, "start [0]");
- }
-
- public void endSession() {
- Log.d(TAG, "end [" + getSessionTimeString() + "]");
- }
-
- // NPExoPlayer.Listener
-
- @Override
- public void onStateChanged(boolean playWhenReady, int state) {
- Log.d(TAG, "state [" + getSessionTimeString() + ", " + playWhenReady + ", "
- + getStateString(state) + "]");
- }
-
- @Override
- public void onError(Exception e) {
- Log.e(TAG, "playerFailed [" + getSessionTimeString() + "]", e);
- }
-
- @Override
- public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
- float pixelWidthHeightRatio) {
- Log.d(TAG, "videoSizeChanged [" + width + ", " + height + ", " + unappliedRotationDegrees
- + ", " + pixelWidthHeightRatio + "]");
- }
-
- // NPExoPlayer.InfoListener
-
- @Override
- public void onBandwidthSample(int elapsedMs, long bytes, long bitrateEstimate) {
- Log.d(TAG, "bandwidth [" + getSessionTimeString() + ", " + bytes + ", "
- + getTimeString(elapsedMs) + ", " + bitrateEstimate + "]");
- }
-
- @Override
- public void onDroppedFrames(int count, long elapsed) {
- Log.d(TAG, "droppedFrames [" + getSessionTimeString() + ", " + count + "]");
- }
-
- @Override
- public void onLoadStarted(int sourceId, long length, int type, int trigger, Format format,
- long mediaStartTimeMs, long mediaEndTimeMs) {
- loadStartTimeMs[sourceId] = SystemClock.elapsedRealtime();
- if (VerboseLogUtil.isTagEnabled(TAG)) {
- Log.v(TAG, "loadStart [" + getSessionTimeString() + ", " + sourceId + ", " + type
- + ", " + mediaStartTimeMs + ", " + mediaEndTimeMs + "]");
- }
- }
-
- @Override
- public void onLoadCompleted(int sourceId, long bytesLoaded, int type, int trigger, Format format,
- long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs) {
- if (VerboseLogUtil.isTagEnabled(TAG)) {
- long downloadTime = SystemClock.elapsedRealtime() - loadStartTimeMs[sourceId];
- Log.v(TAG, "loadEnd [" + getSessionTimeString() + ", " + sourceId + ", " + downloadTime
- + "]");
- }
- }
-
- @Override
- public void onVideoFormatEnabled(Format format, int trigger, long mediaTimeMs) {
- Log.d(TAG, "videoFormat [" + getSessionTimeString() + ", " + format.id + ", "
- + Integer.toString(trigger) + "]");
- }
-
- @Override
- public void onAudioFormatEnabled(Format format, int trigger, long mediaTimeMs) {
- Log.d(TAG, "audioFormat [" + getSessionTimeString() + ", " + format.id + ", "
- + Integer.toString(trigger) + "]");
- }
-
- // NPExoPlayer.InternalErrorListener
-
- @Override
- public void onLoadError(int sourceId, IOException e) {
- printInternalError("loadError", e);
- }
-
- @Override
- public void onRendererInitializationError(Exception e) {
- printInternalError("rendererInitError", e);
- }
-
- @Override
- public void onDrmSessionManagerError(Exception e) {
- printInternalError("drmSessionManagerError", e);
- }
-
- @Override
- public void onDecoderInitializationError(DecoderInitializationException e) {
- printInternalError("decoderInitializationError", e);
- }
-
- @Override
- public void onAudioTrackInitializationError(AudioTrack.InitializationException e) {
- printInternalError("audioTrackInitializationError", e);
- }
-
- @Override
- public void onAudioTrackWriteError(AudioTrack.WriteException e) {
- printInternalError("audioTrackWriteError", e);
- }
-
- @Override
- public void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
- printInternalError("audioTrackUnderrun [" + bufferSize + ", " + bufferSizeMs + ", "
- + elapsedSinceLastFeedMs + "]", null);
- }
-
- @Override
- public void onCryptoError(CryptoException e) {
- printInternalError("cryptoError", e);
- }
-
- @Override
- public void onDecoderInitialized(String decoderName, long elapsedRealtimeMs,
- long initializationDurationMs) {
- Log.d(TAG, "decoderInitialized [" + getSessionTimeString() + ", " + decoderName + "]");
- }
-
- @Override
- public void onAvailableRangeChanged(int sourceId, TimeRange availableRange) {
- availableRangeValuesUs = availableRange.getCurrentBoundsUs(availableRangeValuesUs);
- Log.d(TAG, "availableRange [" + availableRange.isStatic() + ", " + availableRangeValuesUs[0]
- + ", " + availableRangeValuesUs[1] + "]");
- }
-
- private void printInternalError(String type, Exception e) {
- Log.e(TAG, "internalError [" + getSessionTimeString() + ", " + type + "]", e);
- }
-
- private String getStateString(int state) {
- switch (state) {
- case ExoPlayer.STATE_BUFFERING:
- return "B";
- case ExoPlayer.STATE_ENDED:
- return "E";
- case ExoPlayer.STATE_IDLE:
- return "I";
- case ExoPlayer.STATE_PREPARING:
- return "P";
- case ExoPlayer.STATE_READY:
- return "R";
- default:
- return "?";
- }
- }
-
- private String getSessionTimeString() {
- return getTimeString(SystemClock.elapsedRealtime() - sessionStartTimeMs);
- }
-
- private String getTimeString(long timeMs) {
- return TIME_FORMAT.format((timeMs) / 1000f);
- }
-
-}
diff --git a/app/src/main/java/org/schabi/newpipe/player/exoplayer/ExtractorRendererBuilder.java b/app/src/main/java/org/schabi/newpipe/player/exoplayer/ExtractorRendererBuilder.java
deleted file mode 100644
index a74c33bf8..000000000
--- a/app/src/main/java/org/schabi/newpipe/player/exoplayer/ExtractorRendererBuilder.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.schabi.newpipe.player.exoplayer;
-
-import org.schabi.newpipe.player.exoplayer.NPExoPlayer.RendererBuilder;
-
-import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
-import com.google.android.exoplayer.MediaCodecSelector;
-import com.google.android.exoplayer.MediaCodecVideoTrackRenderer;
-import com.google.android.exoplayer.TrackRenderer;
-import com.google.android.exoplayer.audio.AudioCapabilities;
-import com.google.android.exoplayer.extractor.Extractor;
-import com.google.android.exoplayer.extractor.ExtractorSampleSource;
-import com.google.android.exoplayer.text.TextTrackRenderer;
-import com.google.android.exoplayer.upstream.Allocator;
-import com.google.android.exoplayer.upstream.DataSource;
-import com.google.android.exoplayer.upstream.DefaultAllocator;
-import com.google.android.exoplayer.upstream.DefaultBandwidthMeter;
-import com.google.android.exoplayer.upstream.DefaultUriDataSource;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.media.MediaCodec;
-import android.net.Uri;
-
-/**
- * A {@link RendererBuilder} for streams that can be read using an {@link Extractor}.
- */
-public class ExtractorRendererBuilder implements RendererBuilder {
-
- private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
- private static final int BUFFER_SEGMENT_COUNT = 256;
-
- private final Context context;
- private final String userAgent;
- private final Uri uri;
-
- public ExtractorRendererBuilder(Context context, String userAgent, Uri uri) {
- this.context = context;
- this.userAgent = userAgent;
- this.uri = uri;
- }
-
- @Override
- public void buildRenderers(NPExoPlayer player) {
- Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
-
- // Build the video and audio renderers.
- DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(player.getMainHandler(),
- null);
- DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
- ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource, allocator,
- BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE);
- MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
- sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
- player.getMainHandler(), player, 50);
- MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
- MediaCodecSelector.DEFAULT, null, true, player.getMainHandler(), player,
- AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC);
- TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player,
- player.getMainHandler().getLooper());
-
- // Invoke the callback.
- TrackRenderer[] renderers = new TrackRenderer[NPExoPlayer.RENDERER_COUNT];
- renderers[NPExoPlayer.TYPE_VIDEO] = videoRenderer;
- renderers[NPExoPlayer.TYPE_AUDIO] = audioRenderer;
- renderers[NPExoPlayer.TYPE_TEXT] = textRenderer;
- player.onRenderers(renderers, bandwidthMeter);
- }
-
- @Override
- public void cancel() {
- // Do nothing.
- }
-
-}
diff --git a/app/src/main/java/org/schabi/newpipe/player/exoplayer/HlsRendererBuilder.java b/app/src/main/java/org/schabi/newpipe/player/exoplayer/HlsRendererBuilder.java
deleted file mode 100644
index 8e6c2d9f5..000000000
--- a/app/src/main/java/org/schabi/newpipe/player/exoplayer/HlsRendererBuilder.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.schabi.newpipe.player.exoplayer;
-
-import org.schabi.newpipe.player.exoplayer.NPExoPlayer.RendererBuilder;
-
-import com.google.android.exoplayer.DefaultLoadControl;
-import com.google.android.exoplayer.LoadControl;
-import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
-import com.google.android.exoplayer.MediaCodecSelector;
-import com.google.android.exoplayer.MediaCodecVideoTrackRenderer;
-import com.google.android.exoplayer.TrackRenderer;
-import com.google.android.exoplayer.audio.AudioCapabilities;
-import com.google.android.exoplayer.hls.DefaultHlsTrackSelector;
-import com.google.android.exoplayer.hls.HlsChunkSource;
-import com.google.android.exoplayer.hls.HlsMasterPlaylist;
-import com.google.android.exoplayer.hls.HlsPlaylist;
-import com.google.android.exoplayer.hls.HlsPlaylistParser;
-import com.google.android.exoplayer.hls.HlsSampleSource;
-import com.google.android.exoplayer.hls.PtsTimestampAdjusterProvider;
-import com.google.android.exoplayer.metadata.Id3Parser;
-import com.google.android.exoplayer.metadata.MetadataTrackRenderer;
-import com.google.android.exoplayer.text.TextTrackRenderer;
-import com.google.android.exoplayer.text.eia608.Eia608TrackRenderer;
-import com.google.android.exoplayer.upstream.DataSource;
-import com.google.android.exoplayer.upstream.DefaultAllocator;
-import com.google.android.exoplayer.upstream.DefaultBandwidthMeter;
-import com.google.android.exoplayer.upstream.DefaultUriDataSource;
-import com.google.android.exoplayer.util.ManifestFetcher;
-import com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.media.MediaCodec;
-import android.os.Handler;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * A {@link RendererBuilder} for HLS.
- */
-public class HlsRendererBuilder implements RendererBuilder {
-
- private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
- private static final int MAIN_BUFFER_SEGMENTS = 256;
- private static final int TEXT_BUFFER_SEGMENTS = 2;
-
- private final Context context;
- private final String userAgent;
- private final String url;
-
- private AsyncRendererBuilder currentAsyncBuilder;
-
- public HlsRendererBuilder(Context context, String userAgent, String url) {
- this.context = context;
- this.userAgent = userAgent;
- this.url = url;
- }
-
- @Override
- public void buildRenderers(NPExoPlayer player) {
- currentAsyncBuilder = new AsyncRendererBuilder(context, userAgent, url, player);
- currentAsyncBuilder.init();
- }
-
- @Override
- public void cancel() {
- if (currentAsyncBuilder != null) {
- currentAsyncBuilder.cancel();
- currentAsyncBuilder = null;
- }
- }
-
- private static final class AsyncRendererBuilder implements ManifestCallback {
-
- private final Context context;
- private final String userAgent;
- private final String url;
- private final NPExoPlayer player;
- private final ManifestFetcher playlistFetcher;
-
- private boolean canceled;
-
- public AsyncRendererBuilder(Context context, String userAgent, String url, NPExoPlayer player) {
- this.context = context;
- this.userAgent = userAgent;
- this.url = url;
- this.player = player;
- HlsPlaylistParser parser = new HlsPlaylistParser();
- playlistFetcher = new ManifestFetcher<>(url, new DefaultUriDataSource(context, userAgent),
- parser);
- }
-
- public void init() {
- playlistFetcher.singleLoad(player.getMainHandler().getLooper(), this);
- }
-
- public void cancel() {
- canceled = true;
- }
-
- @Override
- public void onSingleManifestError(IOException e) {
- if (canceled) {
- return;
- }
-
- player.onRenderersError(e);
- }
-
- @Override
- public void onSingleManifest(HlsPlaylist manifest) {
- if (canceled) {
- return;
- }
-
- Handler mainHandler = player.getMainHandler();
- LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SEGMENT_SIZE));
- DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
- PtsTimestampAdjusterProvider timestampAdjusterProvider = new PtsTimestampAdjusterProvider();
-
- // Build the video/audio/metadata renderers.
- DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
- HlsChunkSource chunkSource = new HlsChunkSource(true /* isMaster */, dataSource, url,
- manifest, DefaultHlsTrackSelector.newDefaultInstance(context), bandwidthMeter,
- timestampAdjusterProvider, HlsChunkSource.ADAPTIVE_MODE_SPLICE);
- HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl,
- MAIN_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player, NPExoPlayer.TYPE_VIDEO);
- MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
- sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT,
- 5000, mainHandler, player, 50);
- MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
- MediaCodecSelector.DEFAULT, null, true, player.getMainHandler(), player,
- AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC);
- MetadataTrackRenderer