Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] New embeded in fragment video player #834

Closed
wants to merge 67 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
2671883
New video player
avently Nov 11, 2017
7e7757e
Fixed interface elements visibility
avently Nov 11, 2017
aaffef2
Autoplay enabled for all playlists
avently Nov 11, 2017
2829210
Rewrote MainVideoPlayer. It is based on Service
avently Nov 13, 2017
4caa875
Fixed possible crash(es)
avently Nov 15, 2017
8a20743
Status bar is gone in fullscreen mode
avently Nov 15, 2017
0d3bbff
Change current video position via swipe
avently Nov 15, 2017
dfcfb60
Rebased and added fullscreen button
avently Nov 16, 2017
d4ec497
Remove search button from videoDetailFragment
avently Nov 26, 2017
98e0cb5
Play video in fullscreen mode when device in a landscape orientation
avently Nov 26, 2017
b615ead
Disable video while in background
avently Nov 26, 2017
67f07db
Start playing from previous position
avently Nov 26, 2017
0c9c2fe
Fix for situations when autoPlay disabled in settings
avently Nov 26, 2017
451d1d3
Disable fullscreen when device rotates to portrait orientation
avently Nov 26, 2017
89c7d34
Replaced notification view and catched some errors
avently Nov 26, 2017
e534d16
Some playback issues
avently Nov 27, 2017
d792e80
"Continue in background" setting
avently Nov 27, 2017
fc5afc6
"Autoplay always" setting added
avently Nov 28, 2017
b310b1d
Replaced BackgroundPlayer with MainVideoPlayer
avently Nov 28, 2017
0f4fe58
Fixed background playback
avently Nov 28, 2017
c2bb40d
Orientation from preferences will be applied in Activity, not Fragment
avently Nov 30, 2017
da3c1c2
Removed fullscreenButton from view
avently Nov 30, 2017
f94aee2
Renamed xml for player
avently Nov 30, 2017
af3165b
Removed BackgroundPlayer class
avently Nov 30, 2017
2cc2154
Refactored code
avently Dec 1, 2017
f3bca65
Renamed MainVideoPlayer -> MainPlayerService
avently Dec 1, 2017
465500a
Fixed annoying bug with playback after error
avently Dec 2, 2017
e0746c5
Fixed orientation issues
avently Dec 5, 2017
c6c07b2
Notification was visible in some situations
avently Dec 5, 2017
7bb0f39
Simplified code for autoPlay setting and fixed backPressed event
avently Dec 6, 2017
a0483db
Latest PR #895 implemented
avently Dec 6, 2017
9ed98ea
Removed custom autorotation listener
avently Dec 7, 2017
58b4ae6
Added contentObserver
avently Jan 2, 2018
cda7488
Merge remote-tracking branch 'origin/dev' into dev
avently Jan 2, 2018
cba8842
Fixed conflicts with dev
avently Jan 2, 2018
9c79f50
Resolved issues with background playback
avently Jan 10, 2018
a914155
PopupPlayer fixes
avently Jan 10, 2018
d4f9013
Needed methods extracted from PlayerEventListener to different class
avently Jan 10, 2018
e37848c
Small fixes
avently Jan 10, 2018
249d0e8
VideoDetailFragment was blank when background player was called from …
avently Jan 10, 2018
45bcd91
Quality selection improved
avently Jan 10, 2018
7a4f9d1
Merge remote
avently Jan 13, 2018
3176925
Support convertation from all players to all players
avently Jan 13, 2018
8cb5e56
Preparation for something good
avently Jan 16, 2018
2f13385
First stage of merging popup to main player
avently Jan 17, 2018
9616aef
Second stage. Removed unused files
avently Jan 17, 2018
2f370b5
GestureListener changed its home to a new class
avently Jan 17, 2018
7b7b4ff
PlayerImpl changed its home to a new class. Third stage ended.
avently Jan 17, 2018
39b1aac
Added comments and refactored the code.
avently Jan 17, 2018
0d1cf94
Small fixes
avently Jan 18, 2018
dcd61ad
Brightness will be saved and restored across restarts
avently Feb 2, 2018
4264bf9
Made the main service modular
avently Feb 3, 2018
fd81d2b
Removed direct link between activity-fragment
avently Feb 3, 2018
03a060f
Too many changes for one day
avently Feb 3, 2018
5bc809d
Merged the latest changes without videoPlayer option in preferred player
avently Feb 4, 2018
fbae1c5
Code style consistency
avently Feb 4, 2018
48386ec
Merged latest changes
avently Feb 12, 2018
5796a84
fixed issues with previous merge
avently Feb 12, 2018
e28b6ab
PopupPlayer uses quality value from settings
avently Feb 12, 2018
8fd42b8
Hack for hiding titleBar when it wants to show up
avently Feb 13, 2018
eb47e69
Screen rotation via button improved
avently Feb 13, 2018
b804271
Massive conflict resolving
avently Feb 15, 2018
431f9d4
Removed autoplay_through_intent from everywhere
avently Feb 15, 2018
66be00e
Resize mode ZOOM disabled for popup and enchanced for main player
avently Feb 15, 2018
ae6dd19
Merged remote and fixed conflicts
Mar 23, 2018
0ed6a38
Merged remote and adapted UI for playback speed controller
Mar 25, 2018
66bee17
ShowThenHide controls after seek and fix of potential NPE
Apr 1, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 2 additions & 16 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,30 +40,16 @@
android:theme="@style/OldVideoPlayerTheme"
tools:ignore="UnusedAttribute"/>


<service
android:name=".player.BackgroundPlayer"
android:name=".player.MainPlayerService"
android:exported="false"/>

<activity
android:name=".player.BackgroundPlayerActivity"
android:launchMode="singleTask"
android:label="@string/title_activity_background_player"/>

<activity
android:name=".player.PopupVideoPlayerActivity"
android:launchMode="singleTask"
android:label="@string/title_activity_popup_player"/>

<service
android:name=".player.PopupVideoPlayer"
android:exported="false"/>

<activity
android:name=".player.MainVideoPlayer"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTask"/>

<activity
android:name=".settings.SettingsActivity"
android:label="@string/settings"/>
Expand Down
102 changes: 67 additions & 35 deletions app/src/main/java/org/schabi/newpipe/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,17 @@
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.fragments.BackPressable;
import org.schabi.newpipe.fragments.MainFragment;
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
import org.schabi.newpipe.fragments.list.search.SearchFragment;
import org.schabi.newpipe.player.BasePlayer;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.util.StateSaver;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.util.*;

public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
Expand All @@ -74,7 +71,8 @@ public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]");
if (DEBUG)
Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]");

ThemeHelper.setTheme(this, ServiceHelper.getSelectedServiceId(this));

Expand Down Expand Up @@ -127,17 +125,17 @@ public void onDrawerClosed(View drawerView) {
}

private boolean changeService(MenuItem item) {
if (item.getGroupId() == R.id.menu_services_group) {
drawerItems.getMenu().getItem(ServiceHelper.getSelectedServiceId(this)).setChecked(false);
ServiceHelper.setSelectedServiceId(this, item.getTitle().toString());
drawerItems.getMenu().getItem(ServiceHelper.getSelectedServiceId(this)).setChecked(true);
if (item.getGroupId() == R.id.menu_services_group) {
drawerItems.getMenu().getItem(ServiceHelper.getSelectedServiceId(this)).setChecked(false);
ServiceHelper.setSelectedServiceId(this, item.getTitle().toString());
drawerItems.getMenu().getItem(ServiceHelper.getSelectedServiceId(this)).setChecked(true);
headerServiceView.setText("gurken");
} else {
return false;
}
drawer.closeDrawers();
return true;
}
drawer.closeDrawers();
return true;
}

private void setupDrawerFooter() {
ImageButton settings = findViewById(R.id.drawer_settings);
Expand Down Expand Up @@ -187,28 +185,35 @@ protected void onResume() {

SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
if (sharedPreferences.getBoolean(Constants.KEY_THEME_CHANGE, false)) {
if (DEBUG) Log.d(TAG, "Theme has changed, recreating activity...");
if (DEBUG)
Log.d(TAG, "Theme has changed, recreating activity...");

sharedPreferences.edit().putBoolean(Constants.KEY_THEME_CHANGE, false).apply();
// https://stackoverflow.com/questions/10844112/runtimeexception-performing-pause-of-activity-that-is-not-resumed
// Briefly, let the activity resume properly posting the recreate call to end of the message queue
new Handler(Looper.getMainLooper()).post(MainActivity.this::recreate);
}

if (sharedPreferences.getBoolean(Constants.KEY_MAIN_PAGE_CHANGE, false)) {
if (DEBUG) Log.d(TAG, "main page has changed, recreating main fragment...");
if (DEBUG)
Log.d(TAG, "main page has changed, recreating main fragment...");

sharedPreferences.edit().putBoolean(Constants.KEY_MAIN_PAGE_CHANGE, false).apply();
NavigationHelper.openMainActivity(this);
}
}

@Override
protected void onNewIntent(Intent intent) {
if (DEBUG) Log.d(TAG, "onNewIntent() called with: intent = [" + intent + "]");
if (DEBUG)
Log.d(TAG, "onNewIntent() called with: intent = [" + intent + "]");

if (intent != null) {
// Return if launched from a launcher (e.g. Nova Launcher, Pixel Launcher ...)
// to not destroy the already created backstack
String action = intent.getAction();
if ((action != null && action.equals(Intent.ACTION_MAIN)) && intent.hasCategory(Intent.CATEGORY_LAUNCHER)) return;
if ((action != null && action.equals(Intent.ACTION_MAIN)) && intent.hasCategory(Intent.CATEGORY_LAUNCHER))
return;
}

super.onNewIntent(intent);
Expand All @@ -218,18 +223,27 @@ protected void onNewIntent(Intent intent) {

@Override
public void onBackPressed() {
if (DEBUG) Log.d(TAG, "onBackPressed() called");
if (DEBUG)
Log.d(TAG, "onBackPressed() called");

if (sendBackPressedEvent())
return;

if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
finish();
} else
super.onBackPressed();
}

// If current fragment implements BackPressable (i.e. can/wanna handle back press) delegate the back press to it
private boolean sendBackPressedEvent() {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_holder);
// If current fragment implements BackPressable (i.e. can/wanna handle back press) delegate the back press to it
if (fragment instanceof BackPressable) {
if (((BackPressable) fragment).onBackPressed()) return;
if (((BackPressable) fragment).onBackPressed())
return true;
}


if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
finish();
} else super.onBackPressed();
return false;
}

/**
Expand Down Expand Up @@ -270,7 +284,9 @@ private void onHomeButtonPressed() {

@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (DEBUG) Log.d(TAG, "onCreateOptionsMenu() called with: menu = [" + menu + "]");
if (DEBUG)
Log.d(TAG, "onCreateOptionsMenu() called with: menu = [" + menu + "]");

super.onCreateOptionsMenu(menu);

Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_holder);
Expand All @@ -297,23 +313,31 @@ public boolean onCreateOptionsMenu(Menu menu) {

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (DEBUG) Log.d(TAG, "onOptionsItemSelected() called with: item = [" + item + "]");
if (DEBUG)
Log.d(TAG, "onOptionsItemSelected() called with: item = [" + item + "]");

int id = item.getItemId();
Intent hideMainPlayerIntent = new Intent(VideoDetailFragment.ACTION_HIDE_MAIN_PLAYER);

switch (id) {
case android.R.id.home:
sendBackPressedEvent();
onHomeButtonPressed();
return true;
case R.id.action_settings:
NavigationHelper.openSettings(this);
sendBroadcast(hideMainPlayerIntent);
return true;
case R.id.action_show_downloads:
sendBroadcast(hideMainPlayerIntent);
return NavigationHelper.openDownloads(this);
case R.id.action_about:
NavigationHelper.openAbout(this);
sendBroadcast(hideMainPlayerIntent);
return true;
case R.id.action_history:
NavigationHelper.openHistory(this);
sendBroadcast(hideMainPlayerIntent);
return true;
default:
return super.onOptionsItemSelected(item);
Expand All @@ -325,19 +349,23 @@ public boolean onOptionsItemSelected(MenuItem item) {
//////////////////////////////////////////////////////////////////////////*/

private void initFragments() {
if (DEBUG) Log.d(TAG, "initFragments() called");
if (DEBUG)
Log.d(TAG, "initFragments() called");

StateSaver.clearStateFiles();
if (getIntent() != null && getIntent().hasExtra(Constants.KEY_LINK_TYPE)) {
handleIntent(getIntent());
} else NavigationHelper.gotoMainFragment(getSupportFragmentManager());
} else
NavigationHelper.gotoMainFragment(getSupportFragmentManager());
}

/*//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////*/

private void updateDrawerNavigation() {
if (getSupportActionBar() == null) return;
if (getSupportActionBar() == null)
return;

final Toolbar toolbar = findViewById(R.id.toolbar);
final DrawerLayout drawer = findViewById(R.id.drawer_layout);
Expand All @@ -358,16 +386,19 @@ private void updateDrawerNavigation() {
}

private void handleIntent(Intent intent) {
if (DEBUG) Log.d(TAG, "handleIntent() called with: intent = [" + intent + "]");
if (DEBUG)
Log.d(TAG, "handleIntent() called with: intent = [" + intent + "]");

if (intent.hasExtra(Constants.KEY_LINK_TYPE)) {
String url = intent.getStringExtra(Constants.KEY_URL);
int serviceId = intent.getIntExtra(Constants.KEY_SERVICE_ID, 0);
String title = intent.getStringExtra(Constants.KEY_TITLE);
switch (((StreamingService.LinkType) intent.getSerializableExtra(Constants.KEY_LINK_TYPE))) {
case STREAM:
boolean autoPlay = intent.getBooleanExtra(VideoDetailFragment.AUTO_PLAY, false);
NavigationHelper.openVideoDetailFragment(getSupportFragmentManager(), serviceId, url, title, autoPlay);
boolean autoPlay = intent.getBooleanExtra(BasePlayer.AUTO_PLAY, false);
final String intentCacheKey = intent.getStringExtra(BasePlayer.PLAY_QUEUE);
final PlayQueue playQueue = intentCacheKey != null ? SerializedCache.getInstance().take(intentCacheKey, PlayQueue.class) : null;
NavigationHelper.openVideoDetailFragment(getSupportFragmentManager(), serviceId, url, title, autoPlay, playQueue);
break;
case CHANNEL:
NavigationHelper.openChannelFragment(getSupportFragmentManager(), serviceId, url, title);
Expand All @@ -378,11 +409,12 @@ private void handleIntent(Intent intent) {
}
} else if (intent.hasExtra(Constants.KEY_OPEN_SEARCH)) {
String searchQuery = intent.getStringExtra(Constants.KEY_QUERY);
if (searchQuery == null) searchQuery = "";
if (searchQuery == null)
searchQuery = "";
int serviceId = intent.getIntExtra(Constants.KEY_SERVICE_ID, 0);
NavigationHelper.openSearchFragment(getSupportFragmentManager(), serviceId, searchQuery);
} else {
NavigationHelper.gotoMainFragment(getSupportFragmentManager());
}
}
}
}
16 changes: 14 additions & 2 deletions app/src/main/java/org/schabi/newpipe/RouterActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.player.BasePlayer;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.playlist.ChannelPlayQueue;
import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.playlist.PlaylistPlayQueue;
import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper;
Expand Down Expand Up @@ -453,7 +455,7 @@ public Consumer<Info> getResultHandler(Choice choice) {
playQueue = new SinglePlayQueue((StreamInfo) info);

if (playerChoice.equals(videoPlayerKey)) {
NavigationHelper.playOnMainPlayer(this, playQueue);
openMainPlayer(playQueue, choice);
} else if (playerChoice.equals(backgroundPlayerKey)) {
NavigationHelper.enqueueOnBackgroundPlayer(this, playQueue, true);
} else if (playerChoice.equals(popupPlayerKey)) {
Expand All @@ -466,7 +468,7 @@ public Consumer<Info> getResultHandler(Choice choice) {
playQueue = info instanceof ChannelInfo ? new ChannelPlayQueue((ChannelInfo) info) : new PlaylistPlayQueue((PlaylistInfo) info);

if (playerChoice.equals(videoPlayerKey)) {
NavigationHelper.playOnMainPlayer(this, playQueue);
openMainPlayer(playQueue, choice);
} else if (playerChoice.equals(backgroundPlayerKey)) {
NavigationHelper.playOnBackgroundPlayer(this, playQueue);
} else if (playerChoice.equals(popupPlayerKey)) {
Expand All @@ -476,6 +478,16 @@ public Consumer<Info> getResultHandler(Choice choice) {
};
}

private void openMainPlayer(PlayQueue playQueue, Choice choice) {
Intent intent = NavigationHelper.getPlayerIntent(this, MainActivity.class, playQueue);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Constants.KEY_LINK_TYPE, choice.linkType);
intent.putExtra(Constants.KEY_URL, choice.url);
intent.putExtra(Constants.KEY_TITLE, "");
intent.putExtra(BasePlayer.AUTO_PLAY, true);
this.startActivity(intent);
}

@Override
public void onDestroy() {
super.onDestroy();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package org.schabi.newpipe.fragments.detail;

import org.schabi.newpipe.playlist.PlayQueue;

import java.io.Serializable;

class StackItem implements Serializable {
private int serviceId;
private String title;
private String url;
private String title, url;
private PlayQueue playQueue;

StackItem(int serviceId, String url, String title) {
StackItem(int serviceId, String url, String title, PlayQueue playQueue) {
this.serviceId = serviceId;
this.url = url;
this.title = title;
this.playQueue = playQueue;
}

public void setTitle(String title) {
Expand All @@ -29,6 +32,10 @@ public String getUrl() {
return url;
}

public PlayQueue getPlayQueue() {
return playQueue;
}

@Override
public String toString() {
return getServiceId() + ":" + getUrl() + " > " + getTitle();
Expand Down
Loading