2017-09-03 08:04:18 +02:00
|
|
|
/*
|
|
|
|
* Copyright 2017 Mauricio Colli <mauriciocolli@outlook.com>
|
|
|
|
* PopupVideoPlayer.java is part of NewPipe
|
|
|
|
*
|
|
|
|
* License: GPL-3.0+
|
|
|
|
* This program 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.
|
|
|
|
*
|
|
|
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2017-03-09 08:42:40 +01:00
|
|
|
package org.schabi.newpipe.player;
|
|
|
|
|
|
|
|
import android.annotation.SuppressLint;
|
|
|
|
import android.app.NotificationManager;
|
|
|
|
import android.app.PendingIntent;
|
|
|
|
import android.app.Service;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.content.IntentFilter;
|
2017-05-01 07:23:50 +02:00
|
|
|
import android.content.SharedPreferences;
|
2017-03-09 08:42:40 +01:00
|
|
|
import android.content.res.Configuration;
|
|
|
|
import android.graphics.Bitmap;
|
|
|
|
import android.graphics.PixelFormat;
|
2017-03-27 06:08:16 +02:00
|
|
|
import android.os.Build;
|
2017-03-09 08:42:40 +01:00
|
|
|
import android.os.Handler;
|
|
|
|
import android.os.IBinder;
|
2017-05-01 07:23:50 +02:00
|
|
|
import android.preference.PreferenceManager;
|
2017-09-03 08:04:18 +02:00
|
|
|
import android.support.annotation.NonNull;
|
2017-03-09 08:42:40 +01:00
|
|
|
import android.support.v4.app.NotificationCompat;
|
|
|
|
import android.util.DisplayMetrics;
|
|
|
|
import android.util.Log;
|
|
|
|
import android.view.GestureDetector;
|
|
|
|
import android.view.Gravity;
|
|
|
|
import android.view.MotionEvent;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.WindowManager;
|
2017-03-27 06:08:16 +02:00
|
|
|
import android.widget.PopupMenu;
|
2017-03-09 08:42:40 +01:00
|
|
|
import android.widget.RemoteViews;
|
2017-05-08 15:33:26 +02:00
|
|
|
import android.widget.SeekBar;
|
2017-05-01 07:23:50 +02:00
|
|
|
import android.widget.TextView;
|
2017-03-09 08:42:40 +01:00
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
|
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
|
|
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
|
|
|
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
|
|
|
|
|
|
|
import org.schabi.newpipe.BuildConfig;
|
2017-04-09 19:34:00 +02:00
|
|
|
import org.schabi.newpipe.MainActivity;
|
2017-03-09 08:42:40 +01:00
|
|
|
import org.schabi.newpipe.R;
|
2017-04-12 08:07:15 +02:00
|
|
|
import org.schabi.newpipe.ReCaptchaActivity;
|
2017-03-09 08:42:40 +01:00
|
|
|
import org.schabi.newpipe.extractor.MediaFormat;
|
2017-09-03 08:04:18 +02:00
|
|
|
import org.schabi.newpipe.extractor.NewPipe;
|
2017-03-09 08:42:40 +01:00
|
|
|
import org.schabi.newpipe.extractor.StreamingService;
|
2017-09-03 08:04:18 +02:00
|
|
|
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
|
|
|
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
|
|
|
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
|
|
|
|
import org.schabi.newpipe.extractor.services.youtube.YoutubeStreamExtractor;
|
|
|
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
|
|
|
import org.schabi.newpipe.player.old.PlayVideoActivity;
|
|
|
|
import org.schabi.newpipe.report.ErrorActivity;
|
|
|
|
import org.schabi.newpipe.report.UserAction;
|
2017-04-09 19:34:00 +02:00
|
|
|
import org.schabi.newpipe.util.Constants;
|
2017-09-03 08:04:18 +02:00
|
|
|
import org.schabi.newpipe.util.ExtractorHelper;
|
|
|
|
import org.schabi.newpipe.util.ListHelper;
|
2017-04-12 08:07:15 +02:00
|
|
|
import org.schabi.newpipe.util.NavigationHelper;
|
2017-03-27 06:08:16 +02:00
|
|
|
import org.schabi.newpipe.util.ThemeHelper;
|
2017-09-03 08:04:18 +02:00
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
|
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
|
|
|
import io.reactivex.disposables.Disposable;
|
|
|
|
import io.reactivex.functions.Consumer;
|
|
|
|
import io.reactivex.schedulers.Schedulers;
|
2017-03-27 06:08:16 +02:00
|
|
|
|
2017-05-08 15:33:26 +02:00
|
|
|
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
/**
|
2017-04-17 06:19:53 +02:00
|
|
|
* Service Popup Player implementing VideoPlayer
|
2017-03-27 06:08:16 +02:00
|
|
|
*
|
|
|
|
* @author mauriciocolli
|
|
|
|
*/
|
|
|
|
public class PopupVideoPlayer extends Service {
|
2017-03-09 08:42:40 +01:00
|
|
|
private static final String TAG = ".PopupVideoPlayer";
|
2017-04-17 06:19:53 +02:00
|
|
|
private static final boolean DEBUG = BasePlayer.DEBUG;
|
2017-03-09 08:42:40 +01:00
|
|
|
|
|
|
|
private static final int NOTIFICATION_ID = 40028922;
|
2017-03-27 06:08:16 +02:00
|
|
|
public static final String ACTION_CLOSE = "org.schabi.newpipe.player.PopupVideoPlayer.CLOSE";
|
|
|
|
public static final String ACTION_PLAY_PAUSE = "org.schabi.newpipe.player.PopupVideoPlayer.PLAY_PAUSE";
|
|
|
|
public static final String ACTION_OPEN_DETAIL = "org.schabi.newpipe.player.PopupVideoPlayer.OPEN_DETAIL";
|
|
|
|
public static final String ACTION_REPEAT = "org.schabi.newpipe.player.PopupVideoPlayer.REPEAT";
|
2017-03-09 08:42:40 +01:00
|
|
|
|
2017-05-01 07:23:50 +02:00
|
|
|
private static final String POPUP_SAVED_WIDTH = "popup_saved_width";
|
|
|
|
private static final String POPUP_SAVED_X = "popup_saved_x";
|
|
|
|
private static final String POPUP_SAVED_Y = "popup_saved_y";
|
|
|
|
|
2017-03-09 08:42:40 +01:00
|
|
|
private WindowManager windowManager;
|
|
|
|
private WindowManager.LayoutParams windowLayoutParams;
|
|
|
|
private GestureDetector gestureDetector;
|
|
|
|
|
|
|
|
private float screenWidth, screenHeight;
|
|
|
|
private float popupWidth, popupHeight;
|
2017-05-01 07:23:50 +02:00
|
|
|
|
|
|
|
private float minimumWidth, minimumHeight;
|
|
|
|
private float maximumWidth, maximumHeight;
|
2017-03-09 08:42:40 +01:00
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
private final String setAlphaMethodName = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) ? "setImageAlpha" : "setAlpha";
|
2017-03-09 08:42:40 +01:00
|
|
|
private NotificationManager notificationManager;
|
|
|
|
private NotificationCompat.Builder notBuilder;
|
|
|
|
private RemoteViews notRemoteView;
|
|
|
|
|
|
|
|
|
|
|
|
private ImageLoader imageLoader = ImageLoader.getInstance();
|
2017-03-27 06:08:16 +02:00
|
|
|
private DisplayImageOptions displayImageOptions = new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
2017-03-09 08:42:40 +01:00
|
|
|
|
2017-04-17 06:19:53 +02:00
|
|
|
private VideoPlayerImpl playerImpl;
|
2017-09-03 08:04:18 +02:00
|
|
|
private Disposable currentWorker;
|
2017-03-27 06:08:16 +02:00
|
|
|
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Service LifeCycle
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
2017-03-09 08:42:40 +01:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onCreate() {
|
|
|
|
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
|
|
|
notificationManager = ((NotificationManager) getSystemService(NOTIFICATION_SERVICE));
|
2017-03-27 06:08:16 +02:00
|
|
|
|
2017-04-17 06:19:53 +02:00
|
|
|
playerImpl = new VideoPlayerImpl();
|
2017-04-26 21:32:20 +02:00
|
|
|
ThemeHelper.setTheme(this);
|
2017-03-27 06:08:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
public int onStartCommand(final Intent intent, int flags, int startId) {
|
2017-09-03 08:04:18 +02:00
|
|
|
if (DEBUG)
|
|
|
|
Log.d(TAG, "onStartCommand() called with: intent = [" + intent + "], flags = [" + flags + "], startId = [" + startId + "]");
|
2017-03-27 06:08:16 +02:00
|
|
|
if (playerImpl.getPlayer() == null) initPopup();
|
|
|
|
if (!playerImpl.isPlaying()) playerImpl.getPlayer().setPlayWhenReady(true);
|
|
|
|
|
|
|
|
if (imageLoader != null) imageLoader.clearMemoryCache();
|
2017-04-09 19:34:00 +02:00
|
|
|
if (intent.getStringExtra(Constants.KEY_URL) != null) {
|
2017-09-03 08:04:18 +02:00
|
|
|
final int serviceId = intent.getIntExtra(Constants.KEY_SERVICE_ID, 0);
|
|
|
|
final String url = intent.getStringExtra(Constants.KEY_URL);
|
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
playerImpl.setStartedFromNewPipe(false);
|
2017-09-03 08:04:18 +02:00
|
|
|
|
|
|
|
final FetcherHandler fetcherRunnable = new FetcherHandler(this, serviceId, url);
|
|
|
|
currentWorker = ExtractorHelper.getStreamInfo(serviceId,url,false)
|
|
|
|
.subscribeOn(Schedulers.io())
|
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
|
|
.subscribe(new Consumer<StreamInfo>() {
|
|
|
|
@Override
|
|
|
|
public void accept(@NonNull StreamInfo info) throws Exception {
|
|
|
|
fetcherRunnable.onReceive(info);
|
|
|
|
}
|
|
|
|
}, new Consumer<Throwable>() {
|
|
|
|
@Override
|
|
|
|
public void accept(@NonNull Throwable throwable) throws Exception {
|
|
|
|
fetcherRunnable.onError(throwable);
|
|
|
|
}
|
|
|
|
});
|
2017-03-27 06:08:16 +02:00
|
|
|
} else {
|
|
|
|
playerImpl.setStartedFromNewPipe(true);
|
|
|
|
playerImpl.handleIntent(intent);
|
|
|
|
}
|
|
|
|
return START_NOT_STICKY;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onConfigurationChanged(Configuration newConfig) {
|
|
|
|
updateScreenSize();
|
2017-05-01 07:23:50 +02:00
|
|
|
updatePopupSize(windowLayoutParams.width, -1);
|
|
|
|
checkPositionBounds();
|
2017-03-27 06:08:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
if (DEBUG) Log.d(TAG, "onDestroy() called");
|
|
|
|
stopForeground(true);
|
|
|
|
if (playerImpl != null) {
|
|
|
|
playerImpl.destroy();
|
|
|
|
if (playerImpl.getRootView() != null) windowManager.removeView(playerImpl.getRootView());
|
|
|
|
}
|
|
|
|
if (notificationManager != null) notificationManager.cancel(NOTIFICATION_ID);
|
2017-09-03 08:04:18 +02:00
|
|
|
if (currentWorker != null) currentWorker.dispose();
|
2017-05-01 07:23:50 +02:00
|
|
|
savePositionAndSize();
|
2017-03-27 06:08:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public IBinder onBind(Intent intent) {
|
|
|
|
return null;
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Init
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
|
|
|
@SuppressLint("RtlHardcoded")
|
2017-03-09 08:42:40 +01:00
|
|
|
private void initPopup() {
|
|
|
|
if (DEBUG) Log.d(TAG, "initPopup() called");
|
|
|
|
View rootView = View.inflate(this, R.layout.player_popup, null);
|
2017-03-27 06:08:16 +02:00
|
|
|
playerImpl.setup(rootView);
|
|
|
|
|
|
|
|
updateScreenSize();
|
2017-05-01 07:23:50 +02:00
|
|
|
|
|
|
|
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
boolean popupRememberSizeAndPos = sharedPreferences.getBoolean(getString(R.string.popup_remember_size_pos_key), true);
|
|
|
|
|
|
|
|
float defaultSize = getResources().getDimension(R.dimen.popup_default_width);
|
|
|
|
popupWidth = popupRememberSizeAndPos ? sharedPreferences.getFloat(POPUP_SAVED_WIDTH, defaultSize) : defaultSize;
|
|
|
|
|
2017-08-18 14:05:31 +02:00
|
|
|
final int layoutParamType = Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_PHONE : WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
|
|
|
|
2017-03-09 08:42:40 +01:00
|
|
|
windowLayoutParams = new WindowManager.LayoutParams(
|
2017-05-01 07:23:50 +02:00
|
|
|
(int) popupWidth, (int) getMinimumVideoHeight(popupWidth),
|
2017-08-18 14:05:31 +02:00
|
|
|
layoutParamType,
|
2017-03-09 08:42:40 +01:00
|
|
|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
|
|
|
|
PixelFormat.TRANSLUCENT);
|
|
|
|
windowLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
|
|
|
|
|
2017-05-01 07:23:50 +02:00
|
|
|
int centerX = (int) (screenWidth / 2f - popupWidth / 2f);
|
|
|
|
int centerY = (int) (screenHeight / 2f - popupHeight / 2f);
|
|
|
|
windowLayoutParams.x = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_X, centerX) : centerX;
|
|
|
|
windowLayoutParams.y = popupRememberSizeAndPos ? sharedPreferences.getInt(POPUP_SAVED_Y, centerY) : centerY;
|
|
|
|
|
|
|
|
checkPositionBounds();
|
|
|
|
|
2017-03-09 08:42:40 +01:00
|
|
|
MySimpleOnGestureListener listener = new MySimpleOnGestureListener();
|
|
|
|
gestureDetector = new GestureDetector(this, listener);
|
2017-05-01 07:23:50 +02:00
|
|
|
//gestureDetector.setIsLongpressEnabled(false);
|
2017-03-09 08:42:40 +01:00
|
|
|
rootView.setOnTouchListener(listener);
|
2017-03-27 06:08:16 +02:00
|
|
|
playerImpl.getLoadingPanel().setMinimumWidth(windowLayoutParams.width);
|
|
|
|
playerImpl.getLoadingPanel().setMinimumHeight(windowLayoutParams.height);
|
2017-03-09 08:42:40 +01:00
|
|
|
windowManager.addView(rootView, windowLayoutParams);
|
|
|
|
}
|
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Notification
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
2017-03-09 08:42:40 +01:00
|
|
|
|
|
|
|
private NotificationCompat.Builder createNotification() {
|
|
|
|
notRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.player_popup_notification);
|
2017-03-27 06:08:16 +02:00
|
|
|
|
2017-04-17 06:19:53 +02:00
|
|
|
if (playerImpl.getVideoThumbnail() == null) notRemoteView.setImageViewResource(R.id.notificationCover, R.drawable.dummy_thumbnail);
|
|
|
|
else notRemoteView.setImageViewBitmap(R.id.notificationCover, playerImpl.getVideoThumbnail());
|
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
notRemoteView.setTextViewText(R.id.notificationSongName, playerImpl.getVideoTitle());
|
2017-09-03 08:04:18 +02:00
|
|
|
notRemoteView.setTextViewText(R.id.notificationArtist, playerImpl.getUploaderName());
|
2017-03-27 06:08:16 +02:00
|
|
|
|
2017-03-09 08:42:40 +01:00
|
|
|
notRemoteView.setOnClickPendingIntent(R.id.notificationPlayPause,
|
2017-03-27 06:08:16 +02:00
|
|
|
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_PLAY_PAUSE), PendingIntent.FLAG_UPDATE_CURRENT));
|
2017-03-09 08:42:40 +01:00
|
|
|
notRemoteView.setOnClickPendingIntent(R.id.notificationStop,
|
2017-03-27 06:08:16 +02:00
|
|
|
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT));
|
2017-03-09 08:42:40 +01:00
|
|
|
notRemoteView.setOnClickPendingIntent(R.id.notificationContent,
|
2017-03-27 06:08:16 +02:00
|
|
|
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_OPEN_DETAIL), PendingIntent.FLAG_UPDATE_CURRENT));
|
|
|
|
notRemoteView.setOnClickPendingIntent(R.id.notificationRepeat,
|
|
|
|
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT));
|
|
|
|
|
|
|
|
switch (playerImpl.getCurrentRepeatMode()) {
|
|
|
|
case REPEAT_DISABLED:
|
|
|
|
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 77);
|
|
|
|
break;
|
|
|
|
case REPEAT_ONE:
|
|
|
|
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 255);
|
|
|
|
break;
|
|
|
|
case REPEAT_ALL:
|
|
|
|
// Waiting :)
|
|
|
|
break;
|
|
|
|
}
|
2017-03-09 08:42:40 +01:00
|
|
|
|
2017-08-18 14:05:31 +02:00
|
|
|
return new NotificationCompat.Builder(this, getString(R.string.notification_channel_id))
|
2017-03-09 08:42:40 +01:00
|
|
|
.setOngoing(true)
|
2017-03-27 06:08:16 +02:00
|
|
|
.setSmallIcon(R.drawable.ic_play_arrow_white)
|
|
|
|
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
2017-03-09 08:42:40 +01:00
|
|
|
.setContent(notRemoteView);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates the notification, and the play/pause button in it.
|
|
|
|
* Used for changes on the remoteView
|
|
|
|
*
|
|
|
|
* @param drawableId if != -1, sets the drawable with that id on the play/pause button
|
|
|
|
*/
|
|
|
|
private void updateNotification(int drawableId) {
|
|
|
|
if (DEBUG) Log.d(TAG, "updateNotification() called with: drawableId = [" + drawableId + "]");
|
|
|
|
if (notBuilder == null || notRemoteView == null) return;
|
|
|
|
if (drawableId != -1) notRemoteView.setImageViewResource(R.id.notificationPlayPause, drawableId);
|
|
|
|
notificationManager.notify(NOTIFICATION_ID, notBuilder.build());
|
|
|
|
}
|
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Misc
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
2017-03-09 08:42:40 +01:00
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
public void onVideoClose() {
|
|
|
|
if (DEBUG) Log.d(TAG, "onVideoClose() called");
|
2017-05-01 07:23:50 +02:00
|
|
|
savePositionAndSize();
|
2017-03-27 06:08:16 +02:00
|
|
|
stopSelf();
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
2017-04-09 19:34:00 +02:00
|
|
|
public void onOpenDetail(Context context, String videoUrl, String videoTitle) {
|
2017-03-27 06:08:16 +02:00
|
|
|
if (DEBUG) Log.d(TAG, "onOpenDetail() called with: context = [" + context + "], videoUrl = [" + videoUrl + "]");
|
2017-04-09 19:34:00 +02:00
|
|
|
Intent i = new Intent(context, MainActivity.class);
|
|
|
|
i.putExtra(Constants.KEY_SERVICE_ID, 0);
|
|
|
|
i.putExtra(Constants.KEY_URL, videoUrl);
|
|
|
|
i.putExtra(Constants.KEY_TITLE, videoTitle);
|
|
|
|
i.putExtra(Constants.KEY_LINK_TYPE, StreamingService.LinkType.STREAM);
|
|
|
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
2017-06-05 21:33:01 +02:00
|
|
|
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
2017-03-27 06:08:16 +02:00
|
|
|
context.startActivity(i);
|
2017-03-31 20:15:26 +02:00
|
|
|
context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Utils
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
2017-03-09 08:42:40 +01:00
|
|
|
|
2017-05-01 07:23:50 +02:00
|
|
|
private void checkPositionBounds() {
|
2017-09-03 08:04:18 +02:00
|
|
|
if (windowLayoutParams.x > screenWidth - windowLayoutParams.width)
|
|
|
|
windowLayoutParams.x = (int) (screenWidth - windowLayoutParams.width);
|
2017-05-01 07:23:50 +02:00
|
|
|
if (windowLayoutParams.x < 0) windowLayoutParams.x = 0;
|
2017-09-03 08:04:18 +02:00
|
|
|
if (windowLayoutParams.y > screenHeight - windowLayoutParams.height)
|
|
|
|
windowLayoutParams.y = (int) (screenHeight - windowLayoutParams.height);
|
2017-05-01 07:23:50 +02:00
|
|
|
if (windowLayoutParams.y < 0) windowLayoutParams.y = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void savePositionAndSize() {
|
|
|
|
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(PopupVideoPlayer.this);
|
|
|
|
sharedPreferences.edit().putInt(POPUP_SAVED_X, windowLayoutParams.x).apply();
|
|
|
|
sharedPreferences.edit().putInt(POPUP_SAVED_Y, windowLayoutParams.y).apply();
|
|
|
|
sharedPreferences.edit().putFloat(POPUP_SAVED_WIDTH, windowLayoutParams.width).apply();
|
|
|
|
}
|
|
|
|
|
|
|
|
private float getMinimumVideoHeight(float width) {
|
|
|
|
//if (DEBUG) Log.d(TAG, "getMinimumVideoHeight() called with: width = [" + width + "], returned: " + height);
|
|
|
|
return width / (16.0f / 9.0f); // Respect the 16:9 ratio that most videos have
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
private void updateScreenSize() {
|
|
|
|
DisplayMetrics metrics = new DisplayMetrics();
|
|
|
|
windowManager.getDefaultDisplay().getMetrics(metrics);
|
|
|
|
|
|
|
|
screenWidth = metrics.widthPixels;
|
|
|
|
screenHeight = metrics.heightPixels;
|
|
|
|
if (DEBUG) Log.d(TAG, "updateScreenSize() called > screenWidth = " + screenWidth + ", screenHeight = " + screenHeight);
|
2017-05-01 07:23:50 +02:00
|
|
|
|
|
|
|
popupWidth = getResources().getDimension(R.dimen.popup_default_width);
|
|
|
|
popupHeight = getMinimumVideoHeight(popupWidth);
|
|
|
|
|
|
|
|
minimumWidth = getResources().getDimension(R.dimen.popup_minimum_width);
|
|
|
|
minimumHeight = getMinimumVideoHeight(minimumWidth);
|
|
|
|
|
|
|
|
maximumWidth = screenWidth;
|
|
|
|
maximumHeight = screenHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updatePopupSize(int width, int height) {
|
|
|
|
//if (DEBUG) Log.d(TAG, "updatePopupSize() called with: width = [" + width + "], height = [" + height + "]");
|
|
|
|
|
|
|
|
width = (int) (width > maximumWidth ? maximumWidth : width < minimumWidth ? minimumWidth : width);
|
|
|
|
|
|
|
|
if (height == -1) height = (int) getMinimumVideoHeight(width);
|
|
|
|
else height = (int) (height > maximumHeight ? maximumHeight : height < minimumHeight ? minimumHeight : height);
|
|
|
|
|
|
|
|
windowLayoutParams.width = width;
|
|
|
|
windowLayoutParams.height = height;
|
|
|
|
popupWidth = width;
|
|
|
|
popupHeight = height;
|
|
|
|
|
|
|
|
if (DEBUG) Log.d(TAG, "updatePopupSize() updated values: width = [" + width + "], height = [" + height + "]");
|
|
|
|
windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams);
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2017-04-17 06:19:53 +02:00
|
|
|
private class VideoPlayerImpl extends VideoPlayer {
|
2017-05-01 07:23:50 +02:00
|
|
|
private TextView resizingIndicator;
|
|
|
|
|
2017-04-17 06:19:53 +02:00
|
|
|
VideoPlayerImpl() {
|
|
|
|
super("VideoPlayerImpl" + PopupVideoPlayer.TAG, PopupVideoPlayer.this);
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-04-17 06:19:53 +02:00
|
|
|
public void playUrl(String url, String format, boolean autoPlay) {
|
|
|
|
super.playUrl(url, format, autoPlay);
|
2017-03-09 08:42:40 +01:00
|
|
|
|
2017-05-01 07:23:50 +02:00
|
|
|
windowLayoutParams.width = (int) popupWidth;
|
|
|
|
windowLayoutParams.height = (int) getMinimumVideoHeight(popupWidth);
|
2017-03-27 06:08:16 +02:00
|
|
|
windowManager.updateViewLayout(getRootView(), windowLayoutParams);
|
2017-03-09 08:42:40 +01:00
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
notBuilder = createNotification();
|
|
|
|
startForeground(NOTIFICATION_ID, notBuilder.build());
|
2017-04-17 06:19:53 +02:00
|
|
|
}
|
|
|
|
|
2017-05-01 07:23:50 +02:00
|
|
|
@Override
|
|
|
|
public void initViews(View rootView) {
|
|
|
|
super.initViews(rootView);
|
2017-09-03 08:04:18 +02:00
|
|
|
resizingIndicator = rootView.findViewById(R.id.resizing_indicator);
|
2017-05-01 07:23:50 +02:00
|
|
|
}
|
|
|
|
|
2017-04-17 06:19:53 +02:00
|
|
|
@Override
|
|
|
|
public void destroy() {
|
|
|
|
super.destroy();
|
|
|
|
if (notRemoteView != null) notRemoteView.setImageViewBitmap(R.id.notificationCover, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onThumbnailReceived(Bitmap thumbnail) {
|
|
|
|
super.onThumbnailReceived(thumbnail);
|
|
|
|
if (thumbnail != null) {
|
|
|
|
if (notRemoteView != null) notRemoteView.setImageViewBitmap(R.id.notificationCover, thumbnail);
|
|
|
|
updateNotification(-1);
|
|
|
|
}
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
@Override
|
|
|
|
public void onFullScreenButtonClicked() {
|
|
|
|
if (DEBUG) Log.d(TAG, "onFullScreenButtonClicked() called");
|
|
|
|
Intent intent;
|
2017-04-12 08:07:15 +02:00
|
|
|
if (!getSharedPreferences().getBoolean(getResources().getString(R.string.use_old_player_key), false)) {
|
2017-04-17 06:19:53 +02:00
|
|
|
intent = NavigationHelper.getOpenVideoPlayerIntent(context, MainVideoPlayer.class, playerImpl);
|
|
|
|
if (!playerImpl.isStartedFromNewPipe()) intent.putExtra(VideoPlayer.STARTED_FROM_NEWPIPE, false);
|
2017-03-27 06:08:16 +02:00
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
|
|
} else {
|
|
|
|
intent = new Intent(PopupVideoPlayer.this, PlayVideoActivity.class)
|
|
|
|
.putExtra(PlayVideoActivity.VIDEO_TITLE, getVideoTitle())
|
|
|
|
.putExtra(PlayVideoActivity.STREAM_URL, getSelectedStreamUri().toString())
|
|
|
|
.putExtra(PlayVideoActivity.VIDEO_URL, getVideoUrl())
|
|
|
|
.putExtra(PlayVideoActivity.START_POSITION, Math.round(getPlayer().getCurrentPosition() / 1000f));
|
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
2017-04-12 08:07:15 +02:00
|
|
|
context.startActivity(intent);
|
2017-04-17 06:19:53 +02:00
|
|
|
if (playerImpl != null) playerImpl.destroyPlayer();
|
|
|
|
stopSelf();
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
@Override
|
|
|
|
public void onRepeatClicked() {
|
|
|
|
super.onRepeatClicked();
|
|
|
|
switch (getCurrentRepeatMode()) {
|
|
|
|
case REPEAT_DISABLED:
|
|
|
|
// Drawable didn't work on low API :/
|
|
|
|
//notRemoteView.setImageViewResource(R.id.notificationRepeat, R.drawable.ic_repeat_disabled_white);
|
|
|
|
// Set the icon to 30% opacity - 255 (max) * .3
|
|
|
|
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 77);
|
|
|
|
break;
|
|
|
|
case REPEAT_ONE:
|
|
|
|
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 255);
|
|
|
|
break;
|
|
|
|
case REPEAT_ALL:
|
|
|
|
// Waiting :)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
updateNotification(-1);
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
@Override
|
|
|
|
public void onDismiss(PopupMenu menu) {
|
|
|
|
super.onDismiss(menu);
|
2017-05-08 15:33:26 +02:00
|
|
|
if (isPlaying()) hideControls(500, 0);
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
@Override
|
2017-04-17 06:19:53 +02:00
|
|
|
public void onError(Exception exception) {
|
|
|
|
exception.printStackTrace();
|
2017-03-27 06:08:16 +02:00
|
|
|
Toast.makeText(context, "Failed to play this video", Toast.LENGTH_SHORT).show();
|
|
|
|
stopSelf();
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
2017-05-08 15:33:26 +02:00
|
|
|
@Override
|
|
|
|
public void onStopTrackingTouch(SeekBar seekBar) {
|
|
|
|
super.onStopTrackingTouch(seekBar);
|
|
|
|
if (playerImpl.wasPlaying()) {
|
|
|
|
hideControls(100, 0);
|
|
|
|
}
|
|
|
|
}
|
2017-09-03 08:04:18 +02:00
|
|
|
|
2017-08-18 20:07:57 +02:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
2017-04-17 06:19:53 +02:00
|
|
|
// Broadcast Receiver
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void setupBroadcastReceiver(IntentFilter intentFilter) {
|
|
|
|
super.setupBroadcastReceiver(intentFilter);
|
|
|
|
if (DEBUG) Log.d(TAG, "setupBroadcastReceiver() called with: intentFilter = [" + intentFilter + "]");
|
|
|
|
intentFilter.addAction(ACTION_CLOSE);
|
|
|
|
intentFilter.addAction(ACTION_PLAY_PAUSE);
|
|
|
|
intentFilter.addAction(ACTION_OPEN_DETAIL);
|
|
|
|
intentFilter.addAction(ACTION_REPEAT);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onBroadcastReceived(Intent intent) {
|
|
|
|
super.onBroadcastReceived(intent);
|
|
|
|
if (DEBUG) Log.d(TAG, "onBroadcastReceived() called with: intent = [" + intent + "]");
|
|
|
|
switch (intent.getAction()) {
|
|
|
|
case ACTION_CLOSE:
|
|
|
|
onVideoClose();
|
|
|
|
break;
|
|
|
|
case ACTION_PLAY_PAUSE:
|
|
|
|
playerImpl.onVideoPlayPause();
|
|
|
|
break;
|
|
|
|
case ACTION_OPEN_DETAIL:
|
|
|
|
onOpenDetail(PopupVideoPlayer.this, playerImpl.getVideoUrl(), playerImpl.getVideoTitle());
|
|
|
|
break;
|
|
|
|
case ACTION_REPEAT:
|
|
|
|
playerImpl.onRepeatClicked();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-03-27 06:08:16 +02:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// States
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
2017-03-09 08:42:40 +01:00
|
|
|
|
|
|
|
@Override
|
2017-03-27 06:08:16 +02:00
|
|
|
public void onLoading() {
|
|
|
|
super.onLoading();
|
|
|
|
updateNotification(R.drawable.ic_play_arrow_white);
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-03-27 06:08:16 +02:00
|
|
|
public void onPlaying() {
|
|
|
|
super.onPlaying();
|
|
|
|
updateNotification(R.drawable.ic_pause_white);
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-03-27 06:08:16 +02:00
|
|
|
public void onBuffering() {
|
|
|
|
super.onBuffering();
|
|
|
|
updateNotification(R.drawable.ic_play_arrow_white);
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-03-27 06:08:16 +02:00
|
|
|
public void onPaused() {
|
|
|
|
super.onPaused();
|
|
|
|
updateNotification(R.drawable.ic_play_arrow_white);
|
|
|
|
showAndAnimateControl(R.drawable.ic_play_arrow_white, false);
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-03-27 06:08:16 +02:00
|
|
|
public void onPausedSeek() {
|
|
|
|
super.onPausedSeek();
|
|
|
|
updateNotification(R.drawable.ic_play_arrow_white);
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-03-27 06:08:16 +02:00
|
|
|
public void onCompleted() {
|
|
|
|
super.onCompleted();
|
|
|
|
updateNotification(R.drawable.ic_replay_white);
|
|
|
|
showAndAnimateControl(R.drawable.ic_replay_white, false);
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
2017-05-01 07:23:50 +02:00
|
|
|
|
|
|
|
@SuppressWarnings("WeakerAccess")
|
|
|
|
public TextView getResizingIndicator() {
|
|
|
|
return resizingIndicator;
|
|
|
|
}
|
2017-08-18 20:07:57 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onRepeatModeChanged(int i) {
|
|
|
|
}
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private class MySimpleOnGestureListener extends GestureDetector.SimpleOnGestureListener implements View.OnTouchListener {
|
|
|
|
private int initialPopupX, initialPopupY;
|
|
|
|
private boolean isMoving;
|
|
|
|
|
2017-05-01 07:23:50 +02:00
|
|
|
private int onDownPopupWidth = 0;
|
|
|
|
private boolean isResizing;
|
|
|
|
private boolean isResizingRightSide;
|
|
|
|
|
2017-03-09 08:42:40 +01:00
|
|
|
@Override
|
|
|
|
public boolean onDoubleTap(MotionEvent e) {
|
2017-09-03 08:04:18 +02:00
|
|
|
if (DEBUG)
|
|
|
|
Log.d(TAG, "onDoubleTap() called with: e = [" + e + "]" + "rawXy = " + e.getRawX() + ", " + e.getRawY() + ", xy = " + e.getX() + ", " + e.getY());
|
2017-03-27 06:08:16 +02:00
|
|
|
if (!playerImpl.isPlaying()) return false;
|
|
|
|
if (e.getX() > popupWidth / 2) playerImpl.onFastForward();
|
|
|
|
else playerImpl.onFastRewind();
|
2017-03-09 08:42:40 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onSingleTapConfirmed(MotionEvent e) {
|
|
|
|
if (DEBUG) Log.d(TAG, "onSingleTapConfirmed() called with: e = [" + e + "]");
|
2017-03-27 06:08:16 +02:00
|
|
|
if (playerImpl.getPlayer() == null) return false;
|
|
|
|
playerImpl.onVideoPlayPause();
|
2017-03-09 08:42:40 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onDown(MotionEvent e) {
|
|
|
|
if (DEBUG) Log.d(TAG, "onDown() called with: e = [" + e + "]");
|
|
|
|
initialPopupX = windowLayoutParams.x;
|
|
|
|
initialPopupY = windowLayoutParams.y;
|
2017-05-01 07:23:50 +02:00
|
|
|
popupWidth = windowLayoutParams.width;
|
|
|
|
popupHeight = windowLayoutParams.height;
|
|
|
|
onDownPopupWidth = windowLayoutParams.width;
|
2017-03-09 08:42:40 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-05-01 07:23:50 +02:00
|
|
|
@Override
|
|
|
|
public void onLongPress(MotionEvent e) {
|
|
|
|
if (DEBUG) Log.d(TAG, "onLongPress() called with: e = [" + e + "]");
|
|
|
|
playerImpl.showAndAnimateControl(-1, true);
|
|
|
|
playerImpl.getLoadingPanel().setVisibility(View.GONE);
|
2017-05-08 15:33:26 +02:00
|
|
|
|
|
|
|
playerImpl.hideControls(0, 0);
|
|
|
|
animateView(playerImpl.getCurrentDisplaySeek(), false, 0, 0);
|
|
|
|
animateView(playerImpl.getResizingIndicator(), true, 200, 0);
|
2017-05-01 07:23:50 +02:00
|
|
|
|
|
|
|
isResizing = true;
|
|
|
|
isResizingRightSide = e.getRawX() > windowLayoutParams.x + (windowLayoutParams.width / 2f);
|
|
|
|
}
|
|
|
|
|
2017-03-09 08:42:40 +01:00
|
|
|
@Override
|
|
|
|
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
2017-05-01 07:23:50 +02:00
|
|
|
if (isResizing) return false;
|
|
|
|
|
2017-05-08 15:33:26 +02:00
|
|
|
if (playerImpl.getCurrentState() != BasePlayer.STATE_BUFFERING
|
|
|
|
&& (!isMoving || playerImpl.getControlsRoot().getAlpha() != 1f)) playerImpl.showControls(0);
|
2017-03-09 08:42:40 +01:00
|
|
|
isMoving = true;
|
2017-05-01 07:23:50 +02:00
|
|
|
|
2017-03-09 08:42:40 +01:00
|
|
|
float diffX = (int) (e2.getRawX() - e1.getRawX()), posX = (int) (initialPopupX + diffX);
|
|
|
|
float diffY = (int) (e2.getRawY() - e1.getRawY()), posY = (int) (initialPopupY + diffY);
|
|
|
|
|
|
|
|
if (posX > (screenWidth - popupWidth)) posX = (int) (screenWidth - popupWidth);
|
|
|
|
else if (posX < 0) posX = 0;
|
|
|
|
|
|
|
|
if (posY > (screenHeight - popupHeight)) posY = (int) (screenHeight - popupHeight);
|
|
|
|
else if (posY < 0) posY = 0;
|
|
|
|
|
|
|
|
windowLayoutParams.x = (int) posX;
|
|
|
|
windowLayoutParams.y = (int) posY;
|
|
|
|
|
2017-03-27 06:08:16 +02:00
|
|
|
//noinspection PointlessBooleanExpression
|
|
|
|
if (DEBUG && false) Log.d(TAG, "PopupVideoPlayer.onScroll = " +
|
2017-03-09 08:42:40 +01:00
|
|
|
", e1.getRaw = [" + e1.getRawX() + ", " + e1.getRawY() + "]" +
|
|
|
|
", e2.getRaw = [" + e2.getRawX() + ", " + e2.getRawY() + "]" +
|
|
|
|
", distanceXy = [" + distanceX + ", " + distanceY + "]" +
|
|
|
|
", posXy = [" + posX + ", " + posY + "]" +
|
2017-05-01 07:23:50 +02:00
|
|
|
", popupWh = [" + popupWidth + " x " + popupHeight + "]");
|
2017-03-27 06:08:16 +02:00
|
|
|
windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams);
|
2017-03-09 08:42:40 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void onScrollEnd() {
|
|
|
|
if (DEBUG) Log.d(TAG, "onScrollEnd() called");
|
2017-04-17 06:19:53 +02:00
|
|
|
if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == BasePlayer.STATE_PLAYING) {
|
2017-05-08 15:33:26 +02:00
|
|
|
playerImpl.hideControls(300, VideoPlayer.DEFAULT_CONTROLS_HIDE_TIME);
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onTouch(View v, MotionEvent event) {
|
|
|
|
gestureDetector.onTouchEvent(event);
|
2017-05-01 07:23:50 +02:00
|
|
|
if (event.getAction() == MotionEvent.ACTION_MOVE && isResizing && !isMoving) {
|
|
|
|
//if (DEBUG) Log.d(TAG, "onTouch() ACTION_MOVE > v = [" + v + "], e1.getRaw = [" + event.getRawX() + ", " + event.getRawY() + "]");
|
|
|
|
int width;
|
|
|
|
if (isResizingRightSide) width = (int) event.getRawX() - windowLayoutParams.x;
|
|
|
|
else {
|
|
|
|
width = (int) (windowLayoutParams.width + (windowLayoutParams.x - event.getRawX()));
|
|
|
|
if (width > minimumWidth) windowLayoutParams.x = initialPopupX - (width - onDownPopupWidth);
|
|
|
|
}
|
|
|
|
if (width <= maximumWidth && width >= minimumWidth) updatePopupSize(width, -1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.getAction() == MotionEvent.ACTION_UP) {
|
2017-09-03 08:04:18 +02:00
|
|
|
if (DEBUG)
|
|
|
|
Log.d(TAG, "onTouch() ACTION_UP > v = [" + v + "], e1.getRaw = [" + event.getRawX() + ", " + event.getRawY() + "]");
|
2017-05-01 07:23:50 +02:00
|
|
|
if (isMoving) {
|
|
|
|
isMoving = false;
|
|
|
|
onScrollEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isResizing) {
|
|
|
|
isResizing = false;
|
2017-05-08 15:33:26 +02:00
|
|
|
animateView(playerImpl.getResizingIndicator(), false, 100, 0);
|
2017-05-01 07:23:50 +02:00
|
|
|
playerImpl.changeState(playerImpl.getCurrentState());
|
|
|
|
}
|
|
|
|
savePositionAndSize();
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-09-03 08:04:18 +02:00
|
|
|
* Fetcher handler used if open by a link out of NewPipe
|
2017-03-09 08:42:40 +01:00
|
|
|
*/
|
2017-09-03 08:04:18 +02:00
|
|
|
private class FetcherHandler {
|
|
|
|
private final int serviceId;
|
|
|
|
private final String url;
|
|
|
|
|
2017-04-12 08:07:15 +02:00
|
|
|
private final Context context;
|
2017-03-09 08:42:40 +01:00
|
|
|
private final Handler mainHandler;
|
|
|
|
|
2017-09-03 08:04:18 +02:00
|
|
|
FetcherHandler(Context context, int serviceId, String url) {
|
2017-03-09 08:42:40 +01:00
|
|
|
this.mainHandler = new Handler(PopupVideoPlayer.this.getMainLooper());
|
2017-04-12 08:07:15 +02:00
|
|
|
this.context = context;
|
2017-09-03 08:04:18 +02:00
|
|
|
this.url = url;
|
|
|
|
this.serviceId = serviceId;
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
|
|
|
|
2017-04-12 08:07:15 +02:00
|
|
|
public void onReceive(StreamInfo info) {
|
2017-09-03 08:04:18 +02:00
|
|
|
playerImpl.setVideoTitle(info.name);
|
|
|
|
playerImpl.setVideoUrl(info.url);
|
2017-04-17 06:19:53 +02:00
|
|
|
playerImpl.setVideoThumbnailUrl(info.thumbnail_url);
|
2017-09-03 08:04:18 +02:00
|
|
|
playerImpl.setUploaderName(info.uploader_name);
|
2017-04-12 08:07:15 +02:00
|
|
|
|
2017-09-03 08:04:18 +02:00
|
|
|
playerImpl.setVideoStreamsList(new ArrayList<>(ListHelper.getSortedStreamVideosList(context, info.video_streams, info.video_only_streams, false)));
|
|
|
|
playerImpl.setAudioStream(ListHelper.getHighestQualityAudio(info.audio_streams));
|
2017-04-12 08:07:15 +02:00
|
|
|
|
2017-09-03 08:04:18 +02:00
|
|
|
int defaultResolution = ListHelper.getPopupDefaultResolutionIndex(context, playerImpl.getVideoStreamsList());
|
2017-04-12 08:07:15 +02:00
|
|
|
playerImpl.setSelectedIndexStream(defaultResolution);
|
|
|
|
|
|
|
|
if (DEBUG) {
|
2017-09-03 08:04:18 +02:00
|
|
|
Log.d(TAG, "FetcherHandler.StreamExtractor: chosen = "
|
2017-04-12 08:07:15 +02:00
|
|
|
+ MediaFormat.getNameById(info.video_streams.get(defaultResolution).format) + " "
|
|
|
|
+ info.video_streams.get(defaultResolution).resolution + " > "
|
|
|
|
+ info.video_streams.get(defaultResolution).url);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info.start_position > 0) playerImpl.setVideoStartPos(info.start_position * 1000);
|
|
|
|
else playerImpl.setVideoStartPos(-1);
|
|
|
|
|
|
|
|
mainHandler.post(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2017-04-17 06:19:53 +02:00
|
|
|
playerImpl.play(true);
|
2017-04-12 08:07:15 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
imageLoader.resume();
|
|
|
|
imageLoader.loadImage(info.thumbnail_url, displayImageOptions, new SimpleImageLoadingListener() {
|
|
|
|
@Override
|
2017-05-09 05:12:06 +02:00
|
|
|
public void onLoadingComplete(final String imageUri, View view, final Bitmap loadedImage) {
|
|
|
|
if (playerImpl == null || playerImpl.getPlayer() == null) return;
|
2017-09-03 08:04:18 +02:00
|
|
|
if (DEBUG) Log.d(TAG, "FetcherHandler.imageLoader.onLoadingComplete() called with: imageUri = [" + imageUri + "]");
|
2017-04-12 08:07:15 +02:00
|
|
|
mainHandler.post(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
playerImpl.setVideoThumbnail(loadedImage);
|
|
|
|
if (loadedImage != null) notRemoteView.setImageViewBitmap(R.id.notificationCover, loadedImage);
|
|
|
|
updateNotification(-1);
|
|
|
|
}
|
|
|
|
});
|
2017-04-09 19:34:00 +02:00
|
|
|
}
|
2017-04-12 08:07:15 +02:00
|
|
|
});
|
|
|
|
}
|
2017-03-27 06:08:16 +02:00
|
|
|
|
2017-09-03 08:04:18 +02:00
|
|
|
protected void onError(final Throwable exception) {
|
|
|
|
if (DEBUG) Log.d(TAG, "onError() called with: exception = [" + exception + "]");
|
|
|
|
exception.printStackTrace();
|
2017-04-12 08:07:15 +02:00
|
|
|
mainHandler.post(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2017-09-03 08:04:18 +02:00
|
|
|
if (exception instanceof ReCaptchaException) {
|
|
|
|
onReCaptchaException();
|
|
|
|
} else if (exception instanceof IOException) {
|
|
|
|
Toast.makeText(context, R.string.network_error, Toast.LENGTH_LONG).show();
|
|
|
|
} else if (exception instanceof YoutubeStreamExtractor.GemaException) {
|
|
|
|
Toast.makeText(context, R.string.blocked_by_gema, Toast.LENGTH_LONG).show();
|
|
|
|
} else if (exception instanceof YoutubeStreamExtractor.LiveStreamException) {
|
|
|
|
Toast.makeText(context, R.string.live_streams_not_supported, Toast.LENGTH_LONG).show();
|
|
|
|
} else if (exception instanceof ContentNotAvailableException) {
|
|
|
|
Toast.makeText(context, R.string.content_not_available, Toast.LENGTH_LONG).show();
|
|
|
|
} else {
|
|
|
|
int errorId = exception instanceof YoutubeStreamExtractor.DecryptException ? R.string.youtube_signature_decryption_error :
|
|
|
|
exception instanceof ParsingException ? R.string.parsing_error : R.string.general_error;
|
|
|
|
ErrorActivity.reportError(mainHandler, context, exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(UserAction.REQUESTED_STREAM, NewPipe.getNameOfService(serviceId), url, errorId));
|
|
|
|
}
|
2017-04-12 08:07:15 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
stopSelf();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onReCaptchaException() {
|
2017-09-03 08:04:18 +02:00
|
|
|
Toast.makeText(context, R.string.recaptcha_request_toast, Toast.LENGTH_LONG).show();
|
2017-04-12 08:07:15 +02:00
|
|
|
// Starting ReCaptcha Challenge Activity
|
|
|
|
Intent intent = new Intent(context, ReCaptchaActivity.class);
|
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
|
|
context.startActivity(intent);
|
|
|
|
stopSelf();
|
|
|
|
}
|
2017-03-09 08:42:40 +01:00
|
|
|
}
|
2017-03-27 06:08:16 +02:00
|
|
|
|
|
|
|
}
|