diff --git a/app/build.gradle b/app/build.gradle index e7d5539e8..dedab9861 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' -def version = "0.11.0" +def version = "0.11.1" android { compileSdkVersion 28 @@ -15,7 +15,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 28 - versionCode 905 + versionCode 906 versionName version } diff --git a/app/src/main/java/org/jellyfin/androidtv/constants/HomeSectionType.java b/app/src/main/java/org/jellyfin/androidtv/constants/HomeSectionType.java index b1ee58df2..efcd18bd9 100644 --- a/app/src/main/java/org/jellyfin/androidtv/constants/HomeSectionType.java +++ b/app/src/main/java/org/jellyfin/androidtv/constants/HomeSectionType.java @@ -10,7 +10,9 @@ public enum HomeSectionType { RESUME_AUDIO("resumeaudio"), ACTIVE_RECORDINGS("activerecordings"), NEXT_UP("nextup"), - LIVE_TV("livetv"); + LIVE_TV("livetv"), + + NONE("none"); public static HomeSectionType getByName(String name) { for (HomeSectionType type : HomeSectionType.values()) { @@ -25,4 +27,4 @@ public enum HomeSectionType { HomeSectionType(String name) { this.name = name; } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/jellyfin/androidtv/playback/VideoManager.java b/app/src/main/java/org/jellyfin/androidtv/playback/VideoManager.java index ee5e2c30b..f1960ee55 100644 --- a/app/src/main/java/org/jellyfin/androidtv/playback/VideoManager.java +++ b/app/src/main/java/org/jellyfin/androidtv/playback/VideoManager.java @@ -1,21 +1,27 @@ package org.jellyfin.androidtv.playback; import android.app.Activity; +import android.content.Context; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.net.Uri; import android.os.Handler; +import android.os.Looper; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; +import com.google.android.exoplayer2.DefaultRenderersFactory; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.Player; +import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.source.ProgressiveMediaSource; +import com.google.android.exoplayer2.text.TextOutput; +import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.ui.PlayerView; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; @@ -69,6 +75,7 @@ public class VideoManager implements IVLCVout.OnNewVideoLayoutListener { private long mForcedTime = -1; private long mLastTime = -1; private long mMetaDuration = -1; + private long lastExoPlayerPosition = -1; private boolean nativeMode = false; private boolean mSurfaceReady = false; @@ -92,7 +99,19 @@ public class VideoManager implements IVLCVout.OnNewVideoLayoutListener { } else { mSubtitlesSurface.setVisibility(View.GONE); } - mExoPlayer = ExoPlayerFactory.newSimpleInstance(TvApp.getApplication()); + + mExoPlayer = ExoPlayerFactory.newSimpleInstance( + TvApp.getApplication(), + new DefaultRenderersFactory(TvApp.getApplication()) { + @Override + protected void buildTextRenderers(Context context, + TextOutput output, + Looper outputLooper, int extensionRendererMode, + ArrayList out) { + // Do not add text renderers since we handle subtitles + } + }, + new DefaultTrackSelector()); mExoPlayerView = view.findViewById(R.id.exoPlayerView); mExoPlayerView.setPlayer(mExoPlayer); mExoPlayer.addListener(new Player.EventListener() { @@ -169,7 +188,15 @@ public class VideoManager implements IVLCVout.OnNewVideoLayoutListener { } public long getCurrentPosition() { - if (nativeMode) return mExoPlayer.getCurrentPosition(); + if (nativeMode) { + if (mExoPlayer == null) { + return lastExoPlayerPosition; + } else { + long mExoPlayerCurrentPosition = mExoPlayer.getCurrentPosition(); + lastExoPlayerPosition = mExoPlayerCurrentPosition; + return mExoPlayerCurrentPosition; + } + } if (mVlcPlayer == null) return 0; diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/home/HomeFragment.java b/app/src/main/java/org/jellyfin/androidtv/ui/home/HomeFragment.java index cdda41163..1ec35a910 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/home/HomeFragment.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/home/HomeFragment.java @@ -5,6 +5,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.os.Handler; +import android.util.ArrayMap; import org.jellyfin.androidtv.R; import org.jellyfin.androidtv.TvApp; @@ -45,17 +46,11 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import androidx.leanback.widget.ArrayObjectAdapter; import androidx.leanback.widget.ListRow; -import androidx.leanback.widget.OnItemViewClickedListener; -import androidx.leanback.widget.Presenter; -import androidx.leanback.widget.Row; -import androidx.leanback.widget.RowPresenter; public class HomeFragment extends StdBrowseFragment { // Copied from jellyfin-web (homesections.js#getDefaultSection) @@ -65,7 +60,8 @@ public class HomeFragment extends StdBrowseFragment { HomeSectionType.RESUME_AUDIO, HomeSectionType.LIVE_TV, HomeSectionType.NEXT_UP, - HomeSectionType.LATEST_MEDIA + HomeSectionType.LATEST_MEDIA, + HomeSectionType.NONE }; private List rows = new ArrayList<>(); @@ -234,8 +230,14 @@ public class HomeFragment extends StdBrowseFragment { Pattern pattern = Pattern.compile("^homesection(\\d+)$"); // Add sections to map first to make sure they stay in the correct order - Map sections = new TreeMap<>(); + ArrayMap sections = new ArrayMap<>(); + // Set defaults + for (int i = 0; i < DEFAULT_SECTIONS.length; i++) { + sections.put(i, DEFAULT_SECTIONS[i]); + } + + // Overwrite with user-preferred for (String key : prefs.keySet()) { Matcher matcher = pattern.matcher(key); if (!matcher.matches()) continue; @@ -250,14 +252,10 @@ public class HomeFragment extends StdBrowseFragment { // Fallback when no customization is done by the user rows.clear(); - if (sections.size() > 0) { - for (HomeSectionType section : sections.values()) { + // Actually add the sections + for (HomeSectionType section : sections.values()) { + if (section != HomeSectionType.NONE) addSection(section); - } - } else { - for (HomeSectionType section : DEFAULT_SECTIONS) { - addSection(section); - } } loadRows(); diff --git a/app/src/main/java/org/jellyfin/androidtv/util/apiclient/AuthenticationHelper.java b/app/src/main/java/org/jellyfin/androidtv/util/apiclient/AuthenticationHelper.java index 82a740fc6..d1da55971 100644 --- a/app/src/main/java/org/jellyfin/androidtv/util/apiclient/AuthenticationHelper.java +++ b/app/src/main/java/org/jellyfin/androidtv/util/apiclient/AuthenticationHelper.java @@ -51,7 +51,9 @@ public class AuthenticationHelper { public void onClick(DialogInterface dialog, int whichButton) { String addressValue = address.getText().toString(); TvApp.getApplication().getLogger().Debug("Entered address: " + addressValue); - signInToServer(TvApp.getApplication().getConnectionManager(), addressValue, activity); + if (!addressValue.isEmpty()) { + signInToServer(TvApp.getApplication().getConnectionManager(), addressValue, activity); + } } }).show(); } diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index c7b386245..f00197296 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -134,7 +134,7 @@ android:title="@string/pref_enable_acra" android:summaryOn="@string/pref_acra_enabled" android:summaryOff="@string/pref_acra_disabled" - android:defaultValue="false"/> + android:defaultValue="true"/>