From 461255985c3c689ed1a0e25dea339a4c4086ef6e Mon Sep 17 00:00:00 2001 From: okan35 Date: Mon, 21 Sep 2020 21:16:41 +0200 Subject: [PATCH 1/9] play with work --- .../ui/itemdetail/FullDetailsActivity.java | 38 ++++++++++++++++++- .../main/res/menu/menu_details_play_with.xml | 18 +++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/menu/menu_details_play_with.xml diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java index f2c2d3cc42..4a47f6069c 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java @@ -14,6 +14,7 @@ import android.view.MenuItem; import android.view.View; import android.widget.PopupMenu; +import android.widget.Toast; import androidx.leanback.app.BackgroundManager; import androidx.leanback.app.RowsSupportFragment; @@ -40,6 +41,7 @@ import org.jellyfin.androidtv.data.querying.StdItemQuery; import org.jellyfin.androidtv.data.querying.TrailersQuery; import org.jellyfin.androidtv.preference.UserPreferences; +import org.jellyfin.androidtv.preference.constant.PreferredVideoPlayer; import org.jellyfin.androidtv.ui.IRecordingIndicatorView; import org.jellyfin.androidtv.ui.RecordPopup; import org.jellyfin.androidtv.ui.TextUnderButton; @@ -140,7 +142,7 @@ public class FullDetailsActivity extends BaseActivity implements IRecordingIndic private Lazy apiClient = inject(ApiClient.class); private Lazy serializer = inject(GsonJsonSerializer.class); - + private Lazy userPreferences = inject(UserPreferences.class); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -839,6 +841,7 @@ public void onClick(DialogInterface dialog, int which) { private TextUnderButton queueButton = null; private TextUnderButton deleteButton = null; private TextUnderButton moreButton; + private TextUnderButton playWith = null; private void addButtons(int buttonSize) { String buttonLabel; @@ -935,6 +938,8 @@ public void onClick(View v) { } + + mDetailsOverviewRow.addAction(playWith); if (mBaseItem.getLocalTrailerCount() != null && mBaseItem.getLocalTrailerCount() > 0) { TextUnderButton trailer = new TextUnderButton(this, R.drawable.ic_trailer, buttonSize, getString(R.string.lbl_play_trailers), new View.OnClickListener() { @Override @@ -1136,6 +1141,8 @@ public void onClick(View v) { mDetailsOverviewRow.addAction(mPrevButton); + + //now go get our prev episode id EpisodeQuery adjacent = new EpisodeQuery(); adjacent.setUserId(TvApp.getApplication().getCurrentUser().getId()); @@ -1261,6 +1268,15 @@ public void onClick(View v) { } }); + playWith = new TextUnderButton(this, R.drawable.ic_add, buttonSize, 3, "Play with", new View.OnClickListener() { + @Override + public void onClick(View view) { + + PopupMenu more = new PopupMenu(mActivity, view); + more.inflate(R.menu.menu_details_play_with); + more.setOnMenuItemClickListener(playWithMenuListener); + } + }); moreButton.setVisibility(View.GONE); mDetailsOverviewRow.addAction(moreButton); if (mBaseItem.getBaseItemType() != BaseItemType.Episode) showMoreButtonIfNeeded(); //Episodes check for previous and then call this above @@ -1326,6 +1342,26 @@ public boolean onMenuItemClick(MenuItem item) { } }; + PopupMenu.OnMenuItemClickListener playWithMenuListener = new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + switch (item.getItemId()) { + + case R.id.play_with_vlc: + userPreferences.getValue().set(UserPreferences.Companion.getVideoPlayer(), PreferredVideoPlayer.VLC); + return true; + case R.id.play_with_exo: + userPreferences.getValue().set(UserPreferences.Companion.getVideoPlayer(), PreferredVideoPlayer.EXOPLAYER); + return true; + case R.id.play_with_external: + userPreferences.getValue().set(UserPreferences.Companion.getVideoPlayer(), PreferredVideoPlayer.EXTERNAL); + return true; + + } + return false; + } + }; + RecordPopup mRecordPopup; public void showRecordingOptions(String id, final BaseItemDto program, final boolean recordSeries) { if (mRecordPopup == null) { diff --git a/app/src/main/res/menu/menu_details_play_with.xml b/app/src/main/res/menu/menu_details_play_with.xml new file mode 100644 index 0000000000..5a9c3f3241 --- /dev/null +++ b/app/src/main/res/menu/menu_details_play_with.xml @@ -0,0 +1,18 @@ + + + + + + + + From 219545b26acc965c4d2a60ebc9fbfb3946d38952 Mon Sep 17 00:00:00 2001 From: okan35 Date: Tue, 22 Sep 2020 21:02:14 +0200 Subject: [PATCH 2/9] menu is working --- .../ui/itemdetail/FullDetailsActivity.java | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java index 4a47f6069c..e95cadf7f3 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java @@ -841,7 +841,7 @@ public void onClick(DialogInterface dialog, int which) { private TextUnderButton queueButton = null; private TextUnderButton deleteButton = null; private TextUnderButton moreButton; - private TextUnderButton playWith = null; + private TextUnderButton playWithButton = null; private void addButtons(int buttonSize) { String buttonLabel; @@ -939,7 +939,7 @@ public void onClick(View v) { } - mDetailsOverviewRow.addAction(playWith); + if (mBaseItem.getLocalTrailerCount() != null && mBaseItem.getLocalTrailerCount() > 0) { TextUnderButton trailer = new TextUnderButton(this, R.drawable.ic_trailer, buttonSize, getString(R.string.lbl_play_trailers), new View.OnClickListener() { @Override @@ -1267,16 +1267,20 @@ public void onClick(View v) { more.show(); } }); + if (userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.EXTERNAL) { + playWithButton = new TextUnderButton(this, R.drawable.ic_add, buttonSize, 3, "Play with", new View.OnClickListener() { + @Override + public void onClick(View view) { + Toast.makeText(mApplication, "Play With Button", Toast.LENGTH_SHORT).show(); + PopupMenu more = new PopupMenu(mActivity, view); + more.inflate(R.menu.menu_details_play_with); + more.setOnMenuItemClickListener(playWithMenuListener); + more.show(); + } + }); + mDetailsOverviewRow.addAction(playWithButton); + } - playWith = new TextUnderButton(this, R.drawable.ic_add, buttonSize, 3, "Play with", new View.OnClickListener() { - @Override - public void onClick(View view) { - - PopupMenu more = new PopupMenu(mActivity, view); - more.inflate(R.menu.menu_details_play_with); - more.setOnMenuItemClickListener(playWithMenuListener); - } - }); moreButton.setVisibility(View.GONE); mDetailsOverviewRow.addAction(moreButton); if (mBaseItem.getBaseItemType() != BaseItemType.Episode) showMoreButtonIfNeeded(); //Episodes check for previous and then call this above @@ -1349,12 +1353,15 @@ public boolean onMenuItemClick(MenuItem item) { case R.id.play_with_vlc: userPreferences.getValue().set(UserPreferences.Companion.getVideoPlayer(), PreferredVideoPlayer.VLC); + play(mBaseItem, 0, false); return true; case R.id.play_with_exo: userPreferences.getValue().set(UserPreferences.Companion.getVideoPlayer(), PreferredVideoPlayer.EXOPLAYER); + play(mBaseItem, 0, false); return true; case R.id.play_with_external: userPreferences.getValue().set(UserPreferences.Companion.getVideoPlayer(), PreferredVideoPlayer.EXTERNAL); + play(mBaseItem, 0, false); return true; } From 502c3ff71873c87f23611b7aac00f6e72d9cfff5 Mon Sep 17 00:00:00 2001 From: okan35 Date: Sat, 26 Sep 2020 14:21:03 +0200 Subject: [PATCH 3/9] progress on play with feature --- .../androidtv/preference/UserPreferences.kt | 6 +++ .../constant/PreferredVideoPlayer.kt | 8 +++- .../ui/itemdetail/FullDetailsActivity.java | 38 +++++++++++-------- .../ui/playback/PlaybackController.java | 18 +++++++++ .../main/res/menu/menu_details_play_with.xml | 6 +-- app/src/main/res/values/strings.xml | 5 +++ 6 files changed, 62 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/org/jellyfin/androidtv/preference/UserPreferences.kt b/app/src/main/java/org/jellyfin/androidtv/preference/UserPreferences.kt index 43bfb8c1cc..6a5296a291 100644 --- a/app/src/main/java/org/jellyfin/androidtv/preference/UserPreferences.kt +++ b/app/src/main/java/org/jellyfin/androidtv/preference/UserPreferences.kt @@ -174,6 +174,12 @@ class UserPreferences(context: Context) : SharedPreferenceStore( * Include system logs in crash reports */ var acraIncludeSystemLogs = Preference.boolean(ACRA.PREF_ENABLE_SYSTEM_LOGS, true) + + /** + * chosen player for play with button - changes every time user chooses a player with "play with" button + */ + + var chosenPlayer = Preference.enum("chosen_player",PreferredVideoPlayer.VLC) } init { diff --git a/app/src/main/java/org/jellyfin/androidtv/preference/constant/PreferredVideoPlayer.kt b/app/src/main/java/org/jellyfin/androidtv/preference/constant/PreferredVideoPlayer.kt index 097a1070d4..f7516e1ddd 100644 --- a/app/src/main/java/org/jellyfin/androidtv/preference/constant/PreferredVideoPlayer.kt +++ b/app/src/main/java/org/jellyfin/androidtv/preference/constant/PreferredVideoPlayer.kt @@ -26,5 +26,11 @@ enum class PreferredVideoPlayer { * Use external player */ @EnumDisplayOptions(R.string.pref_video_player_external) - EXTERNAL + EXTERNAL, + + /** + * Choose a player - play with button + */ + @EnumDisplayOptions(R.string.pref_video_player_choose) + CHOOSE } diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java index e95cadf7f3..4e423db22e 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java @@ -45,6 +45,7 @@ import org.jellyfin.androidtv.ui.IRecordingIndicatorView; import org.jellyfin.androidtv.ui.RecordPopup; import org.jellyfin.androidtv.ui.TextUnderButton; +import org.jellyfin.androidtv.ui.playback.PlaybackController; import org.jellyfin.androidtv.ui.shared.BaseActivity; import org.jellyfin.androidtv.ui.shared.IMessageListener; import org.jellyfin.androidtv.ui.itemhandling.BaseRowItem; @@ -891,18 +892,25 @@ public void onError(Exception exception) { mDetailsOverviewRow.addAction(mResumeButton); boolean resumeButtonVisible = (mBaseItem.getBaseItemType() == BaseItemType.Series && !mBaseItem.getUserData().getPlayed()) || (mBaseItem.getCanResume()); mResumeButton.setVisibility(resumeButtonVisible ? View.VISIBLE : View.GONE); - - TextUnderButton play = new TextUnderButton(this, R.drawable.ic_play, buttonSize, 2, getString(BaseItemUtils.isLiveTv(mBaseItem) ? R.string.lbl_tune_to_channel : mBaseItem.getIsFolderItem() ? R.string.lbl_play_all : R.string.lbl_play), new View.OnClickListener() { - @Override - public void onClick(View v) { - play(mBaseItem, 0, false); - } - }); - mDetailsOverviewRow.addAction(play); + boolean isPlayerPrefChoose = userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.CHOOSE; + TextUnderButton play = null; + if (!isPlayerPrefChoose) { + play = new TextUnderButton(this, R.drawable.ic_play, buttonSize, 2, getString(BaseItemUtils.isLiveTv(mBaseItem) ? R.string.lbl_tune_to_channel : mBaseItem.getIsFolderItem() ? R.string.lbl_play_all : R.string.lbl_play), new View.OnClickListener() { + @Override + public void onClick(View v) { + play(mBaseItem, 0, false); + } + }); + mDetailsOverviewRow.addAction(play); + } + if (resumeButtonVisible) { mResumeButton.requestFocus(); } else { - play.requestFocus(); + if (!isPlayerPrefChoose) { + play.requestFocus(); + } + } if (!mBaseItem.getIsFolderItem() && !BaseItemUtils.isLiveTv(mBaseItem)) { @@ -1267,11 +1275,10 @@ public void onClick(View v) { more.show(); } }); - if (userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.EXTERNAL) { - playWithButton = new TextUnderButton(this, R.drawable.ic_add, buttonSize, 3, "Play with", new View.OnClickListener() { + if (userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.CHOOSE) { + playWithButton = new TextUnderButton(this, R.drawable.ic_add, buttonSize, 3, getString(R.string.play_with), new View.OnClickListener() { @Override public void onClick(View view) { - Toast.makeText(mApplication, "Play With Button", Toast.LENGTH_SHORT).show(); PopupMenu more = new PopupMenu(mActivity, view); more.inflate(R.menu.menu_details_play_with); more.setOnMenuItemClickListener(playWithMenuListener); @@ -1345,6 +1352,7 @@ public boolean onMenuItemClick(MenuItem item) { return false; } }; + PlaybackController playbackController= new PlaybackController(MediaManager.getCurrentVideoQueue()); PopupMenu.OnMenuItemClickListener playWithMenuListener = new PopupMenu.OnMenuItemClickListener() { @Override @@ -1352,15 +1360,15 @@ public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.play_with_vlc: - userPreferences.getValue().set(UserPreferences.Companion.getVideoPlayer(), PreferredVideoPlayer.VLC); + userPreferences.getValue().set(UserPreferences.Companion.getChosenPlayer(),PreferredVideoPlayer.VLC); play(mBaseItem, 0, false); return true; case R.id.play_with_exo: - userPreferences.getValue().set(UserPreferences.Companion.getVideoPlayer(), PreferredVideoPlayer.EXOPLAYER); + userPreferences.getValue().set(UserPreferences.Companion.getChosenPlayer(),PreferredVideoPlayer.EXOPLAYER); play(mBaseItem, 0, false); return true; case R.id.play_with_external: - userPreferences.getValue().set(UserPreferences.Companion.getVideoPlayer(), PreferredVideoPlayer.EXTERNAL); + userPreferences.getValue().set(UserPreferences.Companion.getChosenPlayer(),PreferredVideoPlayer.EXTERNAL); play(mBaseItem, 0, false); return true; diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java index 5b1858e4ce..016fcc041e 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java @@ -112,6 +112,19 @@ public PlaybackController(List items, IPlaybackOverlayFragment frag useVlc = userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.VLC; } + public PlaybackController(List items) { + mItems = items; + mApplication = TvApp.getApplication(); + mHandler = new Handler(); + + refreshRateSwitchingEnabled = DeviceUtils.is60() && userPreferences.getValue().get(UserPreferences.Companion.getRefreshRateSwitchingEnabled()); + if (refreshRateSwitchingEnabled) getDisplayModes(); + + // Set default value for useVlc field + // when set to auto the default will be exoplayer + useVlc = userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.VLC; + } + public void init(VideoManager mgr) { mVideoManager = mgr; directStreamLiveTv = userPreferences.getValue().get(UserPreferences.Companion.getLiveTvDirectPlayEnabled()); @@ -478,6 +491,11 @@ public void onResponse(StreamInfo internalResponse) { !internalResponse.getMediaSource().getDefaultAudioStream().getCodec().equals("dts"))) && (!DeviceUtils.isFireTvStick() || (vlcResponse.getMediaSource().getVideoStream() != null && vlcResponse.getMediaSource().getVideoStream().getWidth() < 1000)); + } else if (preferredVideoPlayer == PreferredVideoPlayer.CHOOSE) { + PreferredVideoPlayer preferredVideoPlayerByPlayWith = userPreferences.getValue().get(UserPreferences.Companion.getChosenPlayer()); + + + System.out.println("PREFERRED PLAYER " + preferredVideoPlayerByPlayWith.name()); } Timber.i(useVlc ? "Preferring VLC" : "Will use internal player"); diff --git a/app/src/main/res/menu/menu_details_play_with.xml b/app/src/main/res/menu/menu_details_play_with.xml index 5a9c3f3241..898f7612c8 100644 --- a/app/src/main/res/menu/menu_details_play_with.xml +++ b/app/src/main/res/menu/menu_details_play_with.xml @@ -2,16 +2,16 @@ - - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 34c5b2f8fb..c9e6c233f9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -349,6 +349,7 @@ ExoPlayer libVLC External app + Always ask About Preferred media player How long to wait before playing the next item @@ -403,4 +404,8 @@ Item NOT Deleted Turn this option off Just this one + Play with Vlc + Play with Exo Player + Play with External App + Play with From d4f57744feaef863ecd12513ae0c5f82a039ed59 Mon Sep 17 00:00:00 2001 From: okan35 Date: Sat, 26 Sep 2020 20:28:22 +0200 Subject: [PATCH 4/9] working external player --- .../ui/itemdetail/FullDetailsActivity.java | 19 ++++++++++++++++--- .../ui/playback/PlaybackController.java | 7 ++++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java index 4e423db22e..b89dbd6226 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java @@ -45,6 +45,7 @@ import org.jellyfin.androidtv.ui.IRecordingIndicatorView; import org.jellyfin.androidtv.ui.RecordPopup; import org.jellyfin.androidtv.ui.TextUnderButton; +import org.jellyfin.androidtv.ui.playback.ExternalPlayerActivity; import org.jellyfin.androidtv.ui.playback.PlaybackController; import org.jellyfin.androidtv.ui.shared.BaseActivity; import org.jellyfin.androidtv.ui.shared.IMessageListener; @@ -1369,7 +1370,19 @@ public boolean onMenuItemClick(MenuItem item) { return true; case R.id.play_with_external: userPreferences.getValue().set(UserPreferences.Companion.getChosenPlayer(),PreferredVideoPlayer.EXTERNAL); - play(mBaseItem, 0, false); + PlaybackHelper.getItemsToPlay(mBaseItem, false , false, new Response>() { + @Override + public void onResponse(List response) { + if (mBaseItem.getBaseItemType() == BaseItemType.MusicArtist) { + MediaManager.playNow(response); + } else { + Intent intent = new Intent(FullDetailsActivity.this, ExternalPlayerActivity.class); + MediaManager.setCurrentVideoQueue(response); + intent.putExtra("Position", 0); + startActivity(intent); + } + } + }); return true; } @@ -1523,14 +1536,14 @@ public void onResponse(UserItemDataDto response) { } protected void play(final BaseItemDto item, final int pos, final boolean shuffle) { - final Activity activity = this; + PlaybackHelper.getItemsToPlay(item, pos == 0 && item.getBaseItemType() == BaseItemType.Movie, shuffle, new Response>() { @Override public void onResponse(List response) { if (item.getBaseItemType() == BaseItemType.MusicArtist) { MediaManager.playNow(response); } else { - Intent intent = new Intent(activity, mApplication.getPlaybackActivityClass(item.getBaseItemType())); + Intent intent = new Intent(FullDetailsActivity.this, mApplication.getPlaybackActivityClass(item.getBaseItemType())); MediaManager.setCurrentVideoQueue(response); intent.putExtra("Position", pos); startActivity(intent); diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java index 016fcc041e..480ed67055 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java @@ -493,7 +493,12 @@ public void onResponse(StreamInfo internalResponse) { (vlcResponse.getMediaSource().getVideoStream() != null && vlcResponse.getMediaSource().getVideoStream().getWidth() < 1000)); } else if (preferredVideoPlayer == PreferredVideoPlayer.CHOOSE) { PreferredVideoPlayer preferredVideoPlayerByPlayWith = userPreferences.getValue().get(UserPreferences.Companion.getChosenPlayer()); - + if (preferredVideoPlayerByPlayWith == PreferredVideoPlayer.VLC) { + useVlc = true; + } else if (preferredVideoPlayerByPlayWith == PreferredVideoPlayer.EXOPLAYER) { + // Make sure to not use VLC + useVlc = false; + } System.out.println("PREFERRED PLAYER " + preferredVideoPlayerByPlayWith.name()); } From 8ffba55364404c438e35c6e703434caf1f1a3423 Mon Sep 17 00:00:00 2001 From: okan35 Date: Sun, 27 Sep 2020 11:19:27 +0200 Subject: [PATCH 5/9] changes from review --- .../androidtv/preference/SystemPreferences.kt | 7 + .../androidtv/preference/UserPreferences.kt | 6 - .../ui/itemdetail/FullDetailsActivity.java | 129 +++++++++--------- .../ui/playback/PlaybackController.java | 29 +--- app/src/main/res/values/strings.xml | 4 +- 5 files changed, 79 insertions(+), 96 deletions(-) diff --git a/app/src/main/java/org/jellyfin/androidtv/preference/SystemPreferences.kt b/app/src/main/java/org/jellyfin/androidtv/preference/SystemPreferences.kt index 74b5808335..e3d1be9732 100644 --- a/app/src/main/java/org/jellyfin/androidtv/preference/SystemPreferences.kt +++ b/app/src/main/java/org/jellyfin/androidtv/preference/SystemPreferences.kt @@ -1,6 +1,7 @@ package org.jellyfin.androidtv.preference import android.content.Context +import org.jellyfin.androidtv.preference.constant.PreferredVideoPlayer /** * System preferences are not possible to modify by the user. @@ -59,5 +60,11 @@ class SystemPreferences(context: Context) : SharedPreferenceStore( * Stores whether the sports filter is active in the channel guide or not */ val liveTvGuideFilterSports = Preference.boolean("guide_filter_sports", false) + + /** + * chosen player for play with button - changes every time user chooses a player with "play with" button + */ + + var chosenPlayer = Preference.enum("chosen_player", PreferredVideoPlayer.VLC) } } diff --git a/app/src/main/java/org/jellyfin/androidtv/preference/UserPreferences.kt b/app/src/main/java/org/jellyfin/androidtv/preference/UserPreferences.kt index 6a5296a291..43bfb8c1cc 100644 --- a/app/src/main/java/org/jellyfin/androidtv/preference/UserPreferences.kt +++ b/app/src/main/java/org/jellyfin/androidtv/preference/UserPreferences.kt @@ -174,12 +174,6 @@ class UserPreferences(context: Context) : SharedPreferenceStore( * Include system logs in crash reports */ var acraIncludeSystemLogs = Preference.boolean(ACRA.PREF_ENABLE_SYSTEM_LOGS, true) - - /** - * chosen player for play with button - changes every time user chooses a player with "play with" button - */ - - var chosenPlayer = Preference.enum("chosen_player",PreferredVideoPlayer.VLC) } init { diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java index b89dbd6226..74b934a1f8 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java @@ -40,6 +40,7 @@ import org.jellyfin.androidtv.data.querying.SpecialsQuery; import org.jellyfin.androidtv.data.querying.StdItemQuery; import org.jellyfin.androidtv.data.querying.TrailersQuery; +import org.jellyfin.androidtv.preference.SystemPreferences; import org.jellyfin.androidtv.preference.UserPreferences; import org.jellyfin.androidtv.preference.constant.PreferredVideoPlayer; import org.jellyfin.androidtv.ui.IRecordingIndicatorView; @@ -145,6 +146,7 @@ public class FullDetailsActivity extends BaseActivity implements IRecordingIndic private Lazy apiClient = inject(ApiClient.class); private Lazy serializer = inject(GsonJsonSerializer.class); private Lazy userPreferences = inject(UserPreferences.class); + private Lazy systemPreferences = inject(SystemPreferences.class); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -843,7 +845,7 @@ public void onClick(DialogInterface dialog, int which) { private TextUnderButton queueButton = null; private TextUnderButton deleteButton = null; private TextUnderButton moreButton; - private TextUnderButton playWithButton = null; + private TextUnderButton playButton = null; private void addButtons(int buttonSize) { String buttonLabel; @@ -889,65 +891,72 @@ public void onError(Exception exception) { } }); - if (BaseItemUtils.canPlay(mBaseItem)) { - mDetailsOverviewRow.addAction(mResumeButton); - boolean resumeButtonVisible = (mBaseItem.getBaseItemType() == BaseItemType.Series && !mBaseItem.getUserData().getPlayed()) || (mBaseItem.getCanResume()); - mResumeButton.setVisibility(resumeButtonVisible ? View.VISIBLE : View.GONE); - boolean isPlayerPrefChoose = userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.CHOOSE; - TextUnderButton play = null; - if (!isPlayerPrefChoose) { - play = new TextUnderButton(this, R.drawable.ic_play, buttonSize, 2, getString(BaseItemUtils.isLiveTv(mBaseItem) ? R.string.lbl_tune_to_channel : mBaseItem.getIsFolderItem() ? R.string.lbl_play_all : R.string.lbl_play), new View.OnClickListener() { + //playButton becomes playWith button + if (userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.CHOOSE) { + playButton = new TextUnderButton(this, R.drawable.ic_add, buttonSize, 3, getString(R.string.play_with), new View.OnClickListener() { + @Override + public void onClick(View view) { + PopupMenu more = new PopupMenu(mActivity, view); + more.inflate(R.menu.menu_details_play_with); + more.setOnMenuItemClickListener(playWithMenuListener); + more.show(); + } + }); + mDetailsOverviewRow.addAction(playButton); + } else { //here playButton is only a play button + if (BaseItemUtils.canPlay(mBaseItem)) { + mDetailsOverviewRow.addAction(mResumeButton); + boolean resumeButtonVisible = (mBaseItem.getBaseItemType() == BaseItemType.Series && !mBaseItem.getUserData().getPlayed()) || (mBaseItem.getCanResume()); + mResumeButton.setVisibility(resumeButtonVisible ? View.VISIBLE : View.GONE); + + playButton = new TextUnderButton(this, R.drawable.ic_play, buttonSize, 2, getString(BaseItemUtils.isLiveTv(mBaseItem) ? R.string.lbl_tune_to_channel : mBaseItem.getIsFolderItem() ? R.string.lbl_play_all : R.string.lbl_play), new View.OnClickListener() { @Override public void onClick(View v) { play(mBaseItem, 0, false); } }); - mDetailsOverviewRow.addAction(play); - } - - if (resumeButtonVisible) { - mResumeButton.requestFocus(); - } else { - if (!isPlayerPrefChoose) { - play.requestFocus(); - } - - } - if (!mBaseItem.getIsFolderItem() && !BaseItemUtils.isLiveTv(mBaseItem)) { - queueButton = new TextUnderButton(this, R.drawable.ic_add, buttonSize, 2, getString(R.string.lbl_add_to_queue), new View.OnClickListener() { - @Override - public void onClick(View v) { - addItemToQueue(); - } - }); - mDetailsOverviewRow.addAction(queueButton); - } + mDetailsOverviewRow.addAction(playButton); - if (mBaseItem.getIsFolderItem()) { - TextUnderButton shuffle = new TextUnderButton(this, R.drawable.ic_shuffle, buttonSize, 2, getString(R.string.lbl_shuffle_all), new View.OnClickListener() { - @Override - public void onClick(View v) { - play(mBaseItem, 0, true); - } - }); - mDetailsOverviewRow.addAction(shuffle); - } + if (resumeButtonVisible) { + mResumeButton.requestFocus(); + } else { + playButton.requestFocus(); + } - if (mBaseItem.getBaseItemType() == BaseItemType.MusicArtist) { - TextUnderButton imix = new TextUnderButton(this, R.drawable.ic_mix, buttonSize, getString(R.string.lbl_instant_mix), new View.OnClickListener() { - @Override - public void onClick(View v) { - Utils.beep(); - PlaybackHelper.playInstantMix(mBaseItem.getId()); - } - }); - mDetailsOverviewRow.addAction(imix); - } + if (!mBaseItem.getIsFolderItem() && !BaseItemUtils.isLiveTv(mBaseItem)) { + queueButton = new TextUnderButton(this, R.drawable.ic_add, buttonSize, 2, getString(R.string.lbl_add_to_queue), new View.OnClickListener() { + @Override + public void onClick(View v) { + addItemToQueue(); + } + }); + mDetailsOverviewRow.addAction(queueButton); + } - } + if (mBaseItem.getIsFolderItem()) { + TextUnderButton shuffle = new TextUnderButton(this, R.drawable.ic_shuffle, buttonSize, 2, getString(R.string.lbl_shuffle_all), new View.OnClickListener() { + @Override + public void onClick(View v) { + play(mBaseItem, 0, true); + } + }); + mDetailsOverviewRow.addAction(shuffle); + } + if (mBaseItem.getBaseItemType() == BaseItemType.MusicArtist) { + TextUnderButton imix = new TextUnderButton(this, R.drawable.ic_mix, buttonSize, getString(R.string.lbl_instant_mix), new View.OnClickListener() { + @Override + public void onClick(View v) { + Utils.beep(); + PlaybackHelper.playInstantMix(mBaseItem.getId()); + } + }); + mDetailsOverviewRow.addAction(imix); + } + } + } if (mBaseItem.getLocalTrailerCount() != null && mBaseItem.getLocalTrailerCount() > 0) { TextUnderButton trailer = new TextUnderButton(this, R.drawable.ic_trailer, buttonSize, getString(R.string.lbl_play_trailers), new View.OnClickListener() { @@ -1276,18 +1285,7 @@ public void onClick(View v) { more.show(); } }); - if (userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.CHOOSE) { - playWithButton = new TextUnderButton(this, R.drawable.ic_add, buttonSize, 3, getString(R.string.play_with), new View.OnClickListener() { - @Override - public void onClick(View view) { - PopupMenu more = new PopupMenu(mActivity, view); - more.inflate(R.menu.menu_details_play_with); - more.setOnMenuItemClickListener(playWithMenuListener); - more.show(); - } - }); - mDetailsOverviewRow.addAction(playWithButton); - } + moreButton.setVisibility(View.GONE); mDetailsOverviewRow.addAction(moreButton); @@ -1353,23 +1351,22 @@ public boolean onMenuItemClick(MenuItem item) { return false; } }; - PlaybackController playbackController= new PlaybackController(MediaManager.getCurrentVideoQueue()); - PopupMenu.OnMenuItemClickListener playWithMenuListener = new PopupMenu.OnMenuItemClickListener() { + private PopupMenu.OnMenuItemClickListener playWithMenuListener = new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.play_with_vlc: - userPreferences.getValue().set(UserPreferences.Companion.getChosenPlayer(),PreferredVideoPlayer.VLC); + systemPreferences.getValue().set(SystemPreferences.Companion.getChosenPlayer(),PreferredVideoPlayer.VLC); play(mBaseItem, 0, false); return true; case R.id.play_with_exo: - userPreferences.getValue().set(UserPreferences.Companion.getChosenPlayer(),PreferredVideoPlayer.EXOPLAYER); + systemPreferences.getValue().set(SystemPreferences.Companion.getChosenPlayer(),PreferredVideoPlayer.EXOPLAYER); play(mBaseItem, 0, false); return true; case R.id.play_with_external: - userPreferences.getValue().set(UserPreferences.Companion.getChosenPlayer(),PreferredVideoPlayer.EXTERNAL); + systemPreferences.getValue().set(SystemPreferences.Companion.getChosenPlayer(),PreferredVideoPlayer.EXTERNAL); PlaybackHelper.getItemsToPlay(mBaseItem, false , false, new Response>() { @Override public void onResponse(List response) { diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java index 480ed67055..290a2ddf50 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java @@ -14,6 +14,7 @@ import org.jellyfin.androidtv.data.compat.StreamInfo; import org.jellyfin.androidtv.data.compat.SubtitleStreamInfo; import org.jellyfin.androidtv.data.compat.VideoOptions; +import org.jellyfin.androidtv.preference.SystemPreferences; import org.jellyfin.androidtv.preference.UserPreferences; import org.jellyfin.androidtv.preference.constant.PreferredVideoPlayer; import org.jellyfin.androidtv.ui.ImageButton; @@ -57,6 +58,7 @@ public class PlaybackController { private Lazy apiClient = inject(ApiClient.class); private Lazy playbackManager = inject(PlaybackManager.class); private Lazy userPreferences = inject(UserPreferences.class); + private Lazy systemPreferences = inject(SystemPreferences.class); List mItems; VideoManager mVideoManager; @@ -112,19 +114,6 @@ public PlaybackController(List items, IPlaybackOverlayFragment frag useVlc = userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.VLC; } - public PlaybackController(List items) { - mItems = items; - mApplication = TvApp.getApplication(); - mHandler = new Handler(); - - refreshRateSwitchingEnabled = DeviceUtils.is60() && userPreferences.getValue().get(UserPreferences.Companion.getRefreshRateSwitchingEnabled()); - if (refreshRateSwitchingEnabled) getDisplayModes(); - - // Set default value for useVlc field - // when set to auto the default will be exoplayer - useVlc = userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.VLC; - } - public void init(VideoManager mgr) { mVideoManager = mgr; directStreamLiveTv = userPreferences.getValue().get(UserPreferences.Companion.getLiveTvDirectPlayEnabled()); @@ -492,15 +481,11 @@ public void onResponse(StreamInfo internalResponse) { (!DeviceUtils.isFireTvStick() || (vlcResponse.getMediaSource().getVideoStream() != null && vlcResponse.getMediaSource().getVideoStream().getWidth() < 1000)); } else if (preferredVideoPlayer == PreferredVideoPlayer.CHOOSE) { - PreferredVideoPlayer preferredVideoPlayerByPlayWith = userPreferences.getValue().get(UserPreferences.Companion.getChosenPlayer()); - if (preferredVideoPlayerByPlayWith == PreferredVideoPlayer.VLC) { - useVlc = true; - } else if (preferredVideoPlayerByPlayWith == PreferredVideoPlayer.EXOPLAYER) { - // Make sure to not use VLC - useVlc = false; - } - - System.out.println("PREFERRED PLAYER " + preferredVideoPlayerByPlayWith.name()); + PreferredVideoPlayer preferredVideoPlayerByPlayWith = systemPreferences.getValue().get(SystemPreferences.Companion.getChosenPlayer()); + + useVlc = preferredVideoPlayerByPlayWith == PreferredVideoPlayer.VLC; + + Timber.i("PREFERRED PLAYER %s", preferredVideoPlayerByPlayWith.name()); } Timber.i(useVlc ? "Preferring VLC" : "Will use internal player"); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c9e6c233f9..cb04bab2e8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -405,7 +405,7 @@ Turn this option off Just this one Play with Vlc - Play with Exo Player - Play with External App + Play with ExoPlayer + Play with external app Play with From 908f99c8014c494e5828c3aa989997b70131ed2b Mon Sep 17 00:00:00 2001 From: okan35 Date: Sun, 27 Sep 2020 11:26:54 +0200 Subject: [PATCH 6/9] removed unused imports - string change --- .../jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java | 2 -- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java index 74b934a1f8..20264608db 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java @@ -14,7 +14,6 @@ import android.view.MenuItem; import android.view.View; import android.widget.PopupMenu; -import android.widget.Toast; import androidx.leanback.app.BackgroundManager; import androidx.leanback.app.RowsSupportFragment; @@ -47,7 +46,6 @@ import org.jellyfin.androidtv.ui.RecordPopup; import org.jellyfin.androidtv.ui.TextUnderButton; import org.jellyfin.androidtv.ui.playback.ExternalPlayerActivity; -import org.jellyfin.androidtv.ui.playback.PlaybackController; import org.jellyfin.androidtv.ui.shared.BaseActivity; import org.jellyfin.androidtv.ui.shared.IMessageListener; import org.jellyfin.androidtv.ui.itemhandling.BaseRowItem; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cb04bab2e8..ba0a84c2e3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -404,7 +404,7 @@ Item NOT Deleted Turn this option off Just this one - Play with Vlc + Play with libVLC Play with ExoPlayer Play with external app Play with From 401799cb05a3351a5adb12d3868fad679039e23f Mon Sep 17 00:00:00 2001 From: okan35 Date: Mon, 5 Oct 2020 20:57:28 +0200 Subject: [PATCH 7/9] show playWith button on certain screens --- .../jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java index 20264608db..0a5119a08c 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java @@ -890,7 +890,7 @@ public void onError(Exception exception) { }); //playButton becomes playWith button - if (userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.CHOOSE) { + if (userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.CHOOSE && (mBaseItem.getBaseItemType() == BaseItemType.Series || mBaseItem.getBaseItemType() == BaseItemType.Movie || mBaseItem.getBaseItemType() == BaseItemType.Video)) { playButton = new TextUnderButton(this, R.drawable.ic_add, buttonSize, 3, getString(R.string.play_with), new View.OnClickListener() { @Override public void onClick(View view) { From 893a3bfa5b3317992502f25d85d9ff7bac73e46f Mon Sep 17 00:00:00 2001 From: okan35 Date: Sat, 10 Oct 2020 16:22:20 +0200 Subject: [PATCH 8/9] button icon change --- .../jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java index 0a5119a08c..64e4ae1c08 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java @@ -891,7 +891,7 @@ public void onError(Exception exception) { //playButton becomes playWith button if (userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.CHOOSE && (mBaseItem.getBaseItemType() == BaseItemType.Series || mBaseItem.getBaseItemType() == BaseItemType.Movie || mBaseItem.getBaseItemType() == BaseItemType.Video)) { - playButton = new TextUnderButton(this, R.drawable.ic_add, buttonSize, 3, getString(R.string.play_with), new View.OnClickListener() { + playButton = new TextUnderButton(this, R.drawable.ic_play, buttonSize, 3, getString(R.string.play_with), new View.OnClickListener() { @Override public void onClick(View view) { PopupMenu more = new PopupMenu(mActivity, view); From ea11eaadf78b6efdb91e87ff5326bf2a6ef91404 Mon Sep 17 00:00:00 2001 From: okan35 Date: Sun, 18 Oct 2020 19:34:11 +0200 Subject: [PATCH 9/9] episode check added for play with button --- .../jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java index 64e4ae1c08..6e38d7f93e 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemdetail/FullDetailsActivity.java @@ -890,7 +890,7 @@ public void onError(Exception exception) { }); //playButton becomes playWith button - if (userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.CHOOSE && (mBaseItem.getBaseItemType() == BaseItemType.Series || mBaseItem.getBaseItemType() == BaseItemType.Movie || mBaseItem.getBaseItemType() == BaseItemType.Video)) { + if (userPreferences.getValue().get(UserPreferences.Companion.getVideoPlayer()) == PreferredVideoPlayer.CHOOSE && (mBaseItem.getBaseItemType() == BaseItemType.Series || mBaseItem.getBaseItemType() == BaseItemType.Movie || mBaseItem.getBaseItemType() == BaseItemType.Video || mBaseItem.getBaseItemType() == BaseItemType.Episode)) { playButton = new TextUnderButton(this, R.drawable.ic_play, buttonSize, 3, getString(R.string.play_with), new View.OnClickListener() { @Override public void onClick(View view) {