Support track selector

pull/137/head
FongMi 4 years ago
parent 783b3c03c0
commit 0077794f0f
  1. 56
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/DetailActivity.java
  2. 23
      app/src/leanback/res/layout/activity_detail.xml
  3. 2
      app/src/leanback/res/layout/adapter_parse.xml
  4. 9
      app/src/leanback/res/layout/dialog_config.xml
  5. 296
      app/src/leanback/res/layout/view_controller_bottom.xml
  6. 50
      app/src/leanback/res/layout/view_controller_center.xml
  7. 112
      app/src/leanback/res/layout/view_controller_widget.xml
  8. 2
      app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java
  9. 5
      app/src/main/java/com/fongmi/android/tv/player/ExoUtil.java
  10. 272
      app/src/main/java/com/fongmi/android/tv/ui/custom/TrackSelectionDialog.java
  11. 12
      app/src/main/res/drawable/shape_title.xml
  12. 54
      app/src/main/res/layout/dialog_tracks.xml
  13. 26
      app/src/main/res/layout/view_error.xml
  14. 2
      app/src/main/res/values-zh-rCN/strings.xml
  15. 2
      app/src/main/res/values-zh-rTW/strings.xml
  16. 2
      app/src/main/res/values/strings.xml

@ -38,6 +38,7 @@ import com.fongmi.android.tv.net.OKHttp;
import com.fongmi.android.tv.player.ExoUtil;
import com.fongmi.android.tv.player.Players;
import com.fongmi.android.tv.ui.custom.CustomKeyDown;
import com.fongmi.android.tv.ui.custom.TrackSelectionDialog;
import com.fongmi.android.tv.ui.presenter.EpisodePresenter;
import com.fongmi.android.tv.ui.presenter.FlagPresenter;
import com.fongmi.android.tv.ui.presenter.GroupPresenter;
@ -147,6 +148,7 @@ public class DetailActivity extends BaseActivity implements CustomKeyDown.Listen
mControl.scale.setOnClickListener(view -> onScale());
mControl.reset.setOnClickListener(view -> onReset());
mControl.speed.setOnClickListener(view -> onSpeed());
mControl.tracks.setOnClickListener(view -> onTracks());
mControl.ending.setOnClickListener(view -> onEnding());
mControl.opening.setOnClickListener(view -> onOpening());
mControl.interval.setOnClickListener(view -> onInterval());
@ -212,8 +214,8 @@ public class DetailActivity extends BaseActivity implements CustomKeyDown.Listen
private void resetFocus(boolean useParse) {
mControl.exoProgress.setNextFocusUpId(useParse ? R.id.parse : R.id.next);
for (int i = 0; i < mControl.playLayout.getChildCount(); i++) {
mControl.playLayout.getChildAt(i).setNextFocusDownId(useParse ? R.id.parse : com.google.android.exoplayer2.ui.R.id.exo_progress);
for (int i = 0; i < mControl.actionLayout.getChildCount(); i++) {
mControl.actionLayout.getChildAt(i).setNextFocusDownId(useParse ? R.id.parse : com.google.android.exoplayer2.ui.R.id.exo_progress);
}
}
@ -224,9 +226,10 @@ public class DetailActivity extends BaseActivity implements CustomKeyDown.Listen
private void getPlayer(boolean replay) {
Vod.Flag.Episode item = (Vod.Flag.Episode) mEpisodeAdapter.get(getEpisodePosition());
if (mFullscreen && Players.get().getRetry() == 0) Notify.show(ResUtil.getString(R.string.play_ready, item.getName()));
mBinding.widget.title.setText(getString(R.string.detail_title, mBinding.name.getText(), item.getName()));
mViewModel.playerContent(getKey(), getVodFlag().getFlag(), item.getUrl());
mBinding.progress.getRoot().setVisibility(View.VISIBLE);
mBinding.error.getRoot().setVisibility(View.GONE);
mBinding.widget.progress.getRoot().setVisibility(View.VISIBLE);
mBinding.widget.error.setVisibility(View.GONE);
updateHistory(item, replay);
}
@ -272,6 +275,7 @@ public class DetailActivity extends BaseActivity implements CustomKeyDown.Listen
for (int i = 0; i < mFlagAdapter.size(); i++) ((Vod.Flag) mFlagAdapter.get(i)).toggle(mCurrent == i, item);
mEpisodeAdapter.notifyArrayItemRangeChanged(0, mEpisodeAdapter.size());
mHandler.post(() -> mBinding.episode.setSelectedPosition(getEpisodePosition()));
mBinding.widget.title.setText(getString(R.string.detail_title, mBinding.name.getText(), item.getName()));
if (mEpisodeAdapter.size() == 0) return;
getPlayer(false);
}
@ -284,8 +288,8 @@ public class DetailActivity extends BaseActivity implements CustomKeyDown.Listen
private void setParseActivated(Parse item) {
ApiConfig.get().setParse(item);
mBinding.error.getRoot().setVisibility(View.GONE);
mBinding.progress.getRoot().setVisibility(View.VISIBLE);
mBinding.widget.error.setVisibility(View.GONE);
mBinding.widget.progress.getRoot().setVisibility(View.VISIBLE);
Result result = mViewModel.getPlayer().getValue();
if (result != null) Players.get().start(result, true);
mParseAdapter.notifyArrayItemRangeChanged(0, mParseAdapter.size());
@ -423,6 +427,12 @@ public class DetailActivity extends BaseActivity implements CustomKeyDown.Listen
mHistory.update();
}
private void onTracks() {
mHandler.postDelayed(() -> getPlayerView().hideController(), 150);
TrackSelectionDialog.createForPlayer(Players.get().exo(), dialog -> {
}).show(getSupportFragmentManager(), "tracks");
}
private void getPart(String source) {
OKHttp.newCall("http://api.pullword.com/get.php?source=" + URLEncoder.encode(source) + "&param1=0&param2=0&json=1").enqueue(new Callback() {
@Override
@ -483,8 +493,9 @@ public class DetailActivity extends BaseActivity implements CustomKeyDown.Listen
private final Runnable mHideCenter = new Runnable() {
@Override
public void run() {
mBinding.center.action.setImageResource(R.drawable.ic_play);
mBinding.center.getRoot().setVisibility(View.GONE);
mBinding.widget.action.setImageResource(R.drawable.ic_play);
mBinding.widget.center.setVisibility(View.GONE);
mBinding.widget.title.setVisibility(View.GONE);
}
};
@ -512,11 +523,12 @@ public class DetailActivity extends BaseActivity implements CustomKeyDown.Listen
case Player.STATE_IDLE:
break;
case Player.STATE_BUFFERING:
mBinding.progress.getRoot().setVisibility(View.VISIBLE);
mBinding.widget.progress.getRoot().setVisibility(View.VISIBLE);
break;
case Player.STATE_READY:
Players.get().setRetry(0);
mBinding.progress.getRoot().setVisibility(View.GONE);
TrackSelectionDialog.setVisible(mControl.tracks);
mBinding.widget.progress.getRoot().setVisibility(View.GONE);
break;
case Player.STATE_ENDED:
if (Players.get().canNext()) checkNext();
@ -548,9 +560,9 @@ public class DetailActivity extends BaseActivity implements CustomKeyDown.Listen
}
private void onError(String msg) {
mBinding.progress.getRoot().setVisibility(View.GONE);
mBinding.error.getRoot().setVisibility(View.VISIBLE);
mBinding.error.text.setText(msg);
mBinding.widget.progress.getRoot().setVisibility(View.GONE);
mBinding.widget.error.setVisibility(View.VISIBLE);
mBinding.widget.text.setText(msg);
Players.get().stop();
stopTimer();
}
@ -563,10 +575,10 @@ public class DetailActivity extends BaseActivity implements CustomKeyDown.Listen
@Override
public void onSeeking(int time) {
mBinding.center.exoDuration.setText(mControl.exoDuration.getText());
mBinding.center.exoPosition.setText(Players.get().getTime(time));
mBinding.center.action.setImageResource(time > 0 ? R.drawable.ic_forward : R.drawable.ic_rewind);
mBinding.center.getRoot().setVisibility(View.VISIBLE);
mBinding.widget.exoDuration.setText(mControl.exoDuration.getText());
mBinding.widget.exoPosition.setText(Players.get().getTime(time));
mBinding.widget.action.setImageResource(time > 0 ? R.drawable.ic_forward : R.drawable.ic_rewind);
mBinding.widget.center.setVisibility(View.VISIBLE);
}
@Override
@ -587,12 +599,14 @@ public class DetailActivity extends BaseActivity implements CustomKeyDown.Listen
public void onKeyCenter() {
if (Players.get().isPlaying()) {
Players.get().pause();
mBinding.center.getRoot().setVisibility(View.VISIBLE);
mBinding.center.exoPosition.setText(Players.get().getTime(0));
mBinding.center.exoDuration.setText(mControl.exoDuration.getText());
mBinding.widget.title.setVisibility(View.VISIBLE);
mBinding.widget.center.setVisibility(View.VISIBLE);
mBinding.widget.exoPosition.setText(Players.get().getTime(0));
mBinding.widget.exoDuration.setText(mControl.exoDuration.getText());
} else {
Players.get().play();
mBinding.center.getRoot().setVisibility(View.GONE);
mBinding.widget.title.setVisibility(View.GONE);
mBinding.widget.center.setVisibility(View.GONE);
}
}

@ -43,25 +43,10 @@
app:use_controller="false" />
<include
android:id="@+id/progress"
layout="@layout/view_progress"
android:visibility="gone" />
<include
android:id="@+id/error"
layout="@layout/view_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
<include
android:id="@+id/center"
layout="@layout/view_controller_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
android:id="@+id/widget"
layout="@layout/view_controller_widget"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>

@ -8,7 +8,7 @@
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:nextFocusUp="@id/playLayout"
android:nextFocusUp="@id/action"
android:nextFocusDown="@id/exo_progress"
android:singleLine="true"
android:textColor="@color/white"

@ -35,6 +35,7 @@
android:imeOptions="actionDone"
android:importantForAutofill="no"
android:inputType="text"
android:nextFocusDown="@id/positive"
android:singleLine="true"
android:textSize="18sp" />
@ -47,7 +48,7 @@
android:orientation="horizontal">
<TextView
android:id="@+id/negative"
android:id="@+id/positive"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
@ -57,12 +58,12 @@
android:focusableInTouchMode="true"
android:gravity="center"
android:singleLine="true"
android:text="@string/dialog_negative"
android:text="@string/dialog_positive"
android:textColor="@color/white"
android:textSize="14sp" />
<TextView
android:id="@+id/positive"
android:id="@+id/negative"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
@ -71,7 +72,7 @@
android:focusableInTouchMode="true"
android:gravity="center"
android:singleLine="true"
android:text="@string/dialog_positive"
android:text="@string/dialog_negative"
android:textColor="@color/white"
android:textSize="14sp" />

@ -15,148 +15,170 @@
android:paddingEnd="16dp"
android:paddingBottom="8dp">
<LinearLayout
android:id="@+id/playLayout"
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:text="@string/play"
android:textColor="@color/grey_700"
android:textSize="18sp" />
<TextView
android:id="@+id/next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusLeft="@id/next"
android:nextFocusDown="@id/parse"
android:text="@string/play_next"
android:textColor="@color/white"
android:textSize="14sp" />
<TextView
android:id="@+id/prev"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:text="@string/play_prev"
android:textColor="@color/white"
android:textSize="14sp" />
<TextView
android:id="@+id/replay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:text="@string/play_replay"
android:textColor="@color/white"
android:textSize="14sp" />
<TextView
android:id="@+id/speed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="1.00" />
<TextView
android:id="@+id/scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="預設" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:text="@string/play_oped"
android:textColor="@color/grey_700"
android:textSize="18sp" />
android:fillViewport="true"
android:scrollbars="none">
<TextView
android:id="@+id/opening"
<LinearLayout
android:id="@+id/actionLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="00:00" />
<TextView
android:id="@+id/ending"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="00:00" />
<TextView
android:id="@+id/interval"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="15秒" />
<TextView
android:id="@+id/reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusRight="@id/reset"
android:nextFocusDown="@id/parse"
android:text="@string/play_reset"
android:textColor="@color/white"
android:textSize="14sp" />
</LinearLayout>
android:animateLayoutChanges="true"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:text="@string/play"
android:textColor="@color/grey_700"
android:textSize="18sp" />
<TextView
android:id="@+id/next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusLeft="@id/next"
android:nextFocusDown="@id/parse"
android:text="@string/play_next"
android:textColor="@color/white"
android:textSize="14sp" />
<TextView
android:id="@+id/prev"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:text="@string/play_prev"
android:textColor="@color/white"
android:textSize="14sp" />
<TextView
android:id="@+id/replay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:text="@string/play_replay"
android:textColor="@color/white"
android:textSize="14sp" />
<TextView
android:id="@+id/speed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="1.00" />
<TextView
android:id="@+id/scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="預設" />
<TextView
android:id="@+id/tracks"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:text="@string/play_tracks"
android:textColor="@color/white"
android:textSize="14sp"
android:visibility="gone" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:text="@string/play_oped"
android:textColor="@color/grey_700"
android:textSize="18sp" />
<TextView
android:id="@+id/opening"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="00:00" />
<TextView
android:id="@+id/ending"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="00:00" />
<TextView
android:id="@+id/interval"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusDown="@id/parse"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="15秒" />
<TextView
android:id="@+id/reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusRight="@id/reset"
android:nextFocusDown="@id/parse"
android:text="@string/play_reset"
android:textColor="@color/white"
android:textSize="14sp" />
</LinearLayout>
</HorizontalScrollView>
<LinearLayout
android:id="@+id/parseLayout"

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_item_activated"
android:gravity="center"
android:orientation="vertical"
android:padding="@dimen/exo_styled_controls_padding">
<ImageView
android:id="@+id/action"
android:layout_width="52dp"
android:layout_height="52dp"
android:background="?attr/selectableItemBackground"
android:scaleType="fitXY"
android:src="@drawable/ic_play" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/exo_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="16sp"
tools:text="00:00:00" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
android:text="/"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:id="@+id/exo_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="16sp"
tools:text="00:00:00" />
</LinearLayout>
</LinearLayout>

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top|start"
android:background="@drawable/shape_title"
android:letterSpacing="0.02"
android:padding="16dp"
android:shadowColor="@color/grey_700"
android:shadowDx="2"
android:shadowDy="2"
android:shadowRadius="1"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="20sp"
android:visibility="gone"
tools:text="慶餘年第一季:第一集"
tools:visibility="visible" />
<include
android:id="@+id/progress"
layout="@layout/view_progress"
android:visibility="gone" />
<LinearLayout
android:id="@+id/error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/shape_item_activated"
android:gravity="center"
android:orientation="vertical"
android:padding="16dp"
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:layout_width="56dp"
android:layout_height="56dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_vod_error" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textColor="@color/white"
android:textSize="16sp"
tools:text="@string/error_play_format" />
</LinearLayout>
<LinearLayout
android:id="@+id/center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/shape_item_activated"
android:gravity="center"
android:orientation="vertical"
android:padding="16dp"
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:id="@+id/action"
android:layout_width="56dp"
android:layout_height="56dp"
android:background="?attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/ic_play" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/exo_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="16sp"
tools:text="00:00:00" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
android:text="/"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:id="@+id/exo_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="16sp"
tools:text="00:00:00" />
</LinearLayout>
</LinearLayout>
</FrameLayout>

@ -164,7 +164,7 @@ public class SiteViewModel extends ViewModel {
if (site.getType() == 1) params.put("ac", "detail");
params.put("wd", keyword);
String body = OKHttp.newCall(site.getApi(), params).execute().body().string();
SpiderDebug.log(site.getName() +"," +body);
SpiderDebug.log(site.getName() + "," + body);
if (site.getType() == 0) post(site, Result.fromXml(body));
else post(site, Result.fromJson(body));
}

@ -13,6 +13,7 @@ import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.ext.rtmp.RtmpDataSource;
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.ui.CaptionStyleCompat;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSource;
@ -28,7 +29,7 @@ public class ExoUtil {
static ExoPlayer create() {
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(App.get());
renderersFactory.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER);
return new ExoPlayer.Builder(App.get()).setRenderersFactory(renderersFactory).build();
return new ExoPlayer.Builder(App.get()).setRenderersFactory(renderersFactory).setTrackSelector(new DefaultTrackSelector(App.get())).build();
}
public static CaptionStyleCompat getCaptionStyle() {
@ -54,7 +55,7 @@ public class ExoUtil {
}
private static MediaItem.SubtitleConfiguration getConfig(Result result) {
return result.getSub().isEmpty() ? null : new MediaItem.SubtitleConfiguration.Builder(Uri.parse(result.getSub())).setMimeType(MimeTypes.APPLICATION_SUBRIP).setSelectionFlags(C.SELECTION_FLAG_DEFAULT).build();
return result.getSub().isEmpty() ? null : new MediaItem.SubtitleConfiguration.Builder(Uri.parse(result.getSub())).setLabel("Spider").setMimeType(MimeTypes.APPLICATION_SUBRIP).setSelectionFlags(C.SELECTION_FLAG_DEFAULT).build();
}
private static DataSource.Factory getFactory(Map<String, String> headers, String url) {

@ -0,0 +1,272 @@
package com.fongmi.android.tv.ui.custom;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatDialog;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.fongmi.android.tv.player.Players;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.trackselection.TrackSelectionOverride;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
import com.google.android.exoplayer2.ui.R;
import com.google.android.exoplayer2.ui.TrackSelectionView;
import com.google.android.material.tabs.TabLayout;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class TrackSelectionDialog extends DialogFragment {
public static final ImmutableList<Integer> SUPPORTED_TRACK_TYPES = ImmutableList.of(C.TRACK_TYPE_VIDEO, C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_TEXT);
private final SparseArray<TrackSelectionViewFragment> tabFragments;
private final ArrayList<Integer> tabTrackTypes;
private DialogInterface.OnClickListener onClickListener;
private DialogInterface.OnDismissListener onDismissListener;
public TrackSelectionDialog() {
tabFragments = new SparseArray<>();
tabTrackTypes = new ArrayList<>();
setRetainInstance(true);
}
/**
* Returns whether a track selection dialog will have content to display if initialized with the
* specified {@link Player}.
*/
public static void setVisible(View view) {
view.setVisibility(willHaveContent(Players.get().exo().getCurrentTracks()) ? View.VISIBLE : View.GONE);
}
/**
* Returns whether a track selection dialog will have content to display if initialized with the
* specified {@link Tracks}.
*/
public static boolean willHaveContent(Tracks tracks) {
for (Tracks.Group trackGroup : tracks.getGroups()) {
if (SUPPORTED_TRACK_TYPES.contains(trackGroup.getType())) {
return true;
}
}
return false;
}
/**
* Creates a dialog for a given {@link Player}, whose parameters will be automatically updated
* when tracks are selected.
*
* @param player The {@link Player}.
* @param onDismissListener A {@link DialogInterface.OnDismissListener} to call when the dialog is
* dismissed.
*/
public static TrackSelectionDialog createForPlayer(Player player, DialogInterface.OnDismissListener onDismissListener) {
return createForTracksAndParameters(player.getCurrentTracks(), player.getTrackSelectionParameters(), true, false, player::setTrackSelectionParameters, onDismissListener);
}
/**
* Creates a dialog for given {@link Tracks} and {@link TrackSelectionParameters}.
*
* @param tracks The {@link Tracks} describing the tracks to display.
* @param trackSelectionParameters The initial {@link TrackSelectionParameters}.
* @param allowAdaptiveSelections Whether adaptive selections (consisting of more than one track)
* can be made.
* @param allowMultipleOverrides Whether tracks from multiple track groups can be selected.
* @param trackSelectionListener Called when tracks are selected.
* @param onDismissListener {@link DialogInterface.OnDismissListener} called when the dialog is
* dismissed.
*/
public static TrackSelectionDialog createForTracksAndParameters(Tracks tracks, TrackSelectionParameters trackSelectionParameters, boolean allowAdaptiveSelections, boolean allowMultipleOverrides, TrackSelectionListener trackSelectionListener, DialogInterface.OnDismissListener onDismissListener) {
TrackSelectionDialog trackSelectionDialog = new TrackSelectionDialog();
trackSelectionDialog.init(tracks, trackSelectionParameters, allowAdaptiveSelections, allowMultipleOverrides, (dialog, which) -> {
TrackSelectionParameters.Builder builder = trackSelectionParameters.buildUpon();
for (int i = 0; i < SUPPORTED_TRACK_TYPES.size(); i++) {
int trackType = SUPPORTED_TRACK_TYPES.get(i);
builder.setTrackTypeDisabled(trackType, trackSelectionDialog.getIsDisabled(trackType));
builder.clearOverridesOfType(trackType);
Map<TrackGroup, TrackSelectionOverride> overrides = trackSelectionDialog.getOverrides(trackType);
for (TrackSelectionOverride override : overrides.values()) builder.addOverride(override);
}
trackSelectionListener.onTracksSelected(builder.build());
}, onDismissListener);
return trackSelectionDialog;
}
private static String getTrackTypeString(Resources resources, @C.TrackType int trackType) {
switch (trackType) {
case C.TRACK_TYPE_VIDEO:
return resources.getString(R.string.exo_track_selection_title_video);
case C.TRACK_TYPE_AUDIO:
return resources.getString(R.string.exo_track_selection_title_audio);
case C.TRACK_TYPE_TEXT:
return resources.getString(R.string.exo_track_selection_title_text);
default:
throw new IllegalArgumentException();
}
}
private void init(Tracks tracks, TrackSelectionParameters trackSelectionParameters, boolean allowAdaptiveSelections, boolean allowMultipleOverrides, DialogInterface.OnClickListener onClickListener, DialogInterface.OnDismissListener onDismissListener) {
this.onClickListener = onClickListener;
this.onDismissListener = onDismissListener;
for (int i = 0; i < SUPPORTED_TRACK_TYPES.size(); i++) {
@C.TrackType int trackType = SUPPORTED_TRACK_TYPES.get(i);
ArrayList<Tracks.Group> trackGroups = new ArrayList<>();
for (Tracks.Group trackGroup : tracks.getGroups()) {
if (trackGroup.getType() == trackType) {
trackGroups.add(trackGroup);
}
}
if (!trackGroups.isEmpty()) {
TrackSelectionViewFragment tabFragment = new TrackSelectionViewFragment();
tabFragment.init(trackGroups, trackSelectionParameters.disabledTrackTypes.contains(trackType), trackSelectionParameters.overrides, allowAdaptiveSelections, allowMultipleOverrides);
tabFragments.put(trackType, tabFragment);
tabTrackTypes.add(trackType);
}
}
}
/**
* Returns whether the disabled option is selected for the specified track type.
*
* @param trackType The track type.
* @return Whether the disabled option is selected for the track type.
*/
public boolean getIsDisabled(int trackType) {
TrackSelectionViewFragment trackView = tabFragments.get(trackType);
return trackView != null && trackView.isDisabled;
}
/**
* Returns the selected track overrides for the specified track type.
*
* @param trackType The track type.
* @return The track overrides for the track type.
*/
public Map<TrackGroup, TrackSelectionOverride> getOverrides(int trackType) {
TrackSelectionViewFragment trackView = tabFragments.get(trackType);
return trackView == null ? Collections.emptyMap() : trackView.overrides;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = new AppCompatDialog(getActivity());
dialog.getWindow().setDimAmount(0);
return dialog;
}
@Override
public void onDismiss(@NonNull DialogInterface dialog) {
super.onDismiss(dialog);
onDismissListener.onDismiss(dialog);
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View dialogView = inflater.inflate(com.fongmi.android.tv.R.layout.dialog_tracks, container, false);
TabLayout tabLayout = dialogView.findViewById(com.fongmi.android.tv.R.id.track_selection_dialog_tab_layout);
ViewPager viewPager = dialogView.findViewById(com.fongmi.android.tv.R.id.track_selection_dialog_view_pager);
TextView cancelButton = dialogView.findViewById(com.fongmi.android.tv.R.id.track_selection_dialog_cancel_button);
TextView okButton = dialogView.findViewById(com.fongmi.android.tv.R.id.track_selection_dialog_ok_button);
viewPager.setAdapter(new FragmentAdapter(getChildFragmentManager()));
tabLayout.setupWithViewPager(viewPager);
tabLayout.setVisibility(tabFragments.size() > 1 ? View.VISIBLE : View.GONE);
cancelButton.setOnClickListener(view -> dismiss());
okButton.setOnClickListener(view -> {
onClickListener.onClick(getDialog(), DialogInterface.BUTTON_POSITIVE);
dismiss();
});
return dialogView;
}
public interface TrackSelectionListener {
void onTracksSelected(TrackSelectionParameters trackSelectionParameters);
}
/**
* Fragment to show a track selection in tab of the track selection dialog.
*/
public static final class TrackSelectionViewFragment extends Fragment implements TrackSelectionView.TrackSelectionListener {
private List<Tracks.Group> trackGroups;
private boolean allowAdaptiveSelections;
private boolean allowMultipleOverrides;
Map<TrackGroup, TrackSelectionOverride> overrides;
boolean isDisabled;
public TrackSelectionViewFragment() {
setRetainInstance(true);
}
public void init(List<Tracks.Group> trackGroups, boolean isDisabled, Map<TrackGroup, TrackSelectionOverride> overrides, boolean allowAdaptiveSelections, boolean allowMultipleOverrides) {
this.trackGroups = trackGroups;
this.isDisabled = isDisabled;
this.allowAdaptiveSelections = allowAdaptiveSelections;
this.allowMultipleOverrides = allowMultipleOverrides;
// TrackSelectionView does this filtering internally, but we need to do it here as well to
// handle the case where the TrackSelectionView is never created.
this.overrides = new HashMap<>(TrackSelectionView.filterOverrides(overrides, trackGroups, allowMultipleOverrides));
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.exo_track_selection_dialog, container, /* attachToRoot= */ false);
TrackSelectionView trackSelectionView = rootView.findViewById(R.id.exo_track_selection_view);
trackSelectionView.setShowDisableOption(true);
trackSelectionView.setAllowMultipleOverrides(allowMultipleOverrides);
trackSelectionView.setAllowAdaptiveSelections(allowAdaptiveSelections);
trackSelectionView.init(trackGroups, isDisabled, overrides, null, this);
return rootView;
}
@Override
public void onTrackSelectionChanged(boolean isDisabled, @NonNull Map<TrackGroup, TrackSelectionOverride> overrides) {
this.isDisabled = isDisabled;
this.overrides = overrides;
}
}
private final class FragmentAdapter extends FragmentPagerAdapter {
public FragmentAdapter(FragmentManager fragmentManager) {
super(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
return tabFragments.get(tabTrackTypes.get(position));
}
@Override
public int getCount() {
return tabTrackTypes.size();
}
@Override
public CharSequence getPageTitle(int position) {
return getTrackTypeString(getResources(), tabTrackTypes.get(position));
}
}
}

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="270"
android:centerColor="#4D000000"
android:endColor="#00000000"
android:startColor="#99000000"
android:type="linear" />
</shape>

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.viewpager.widget.ViewPager
android:id="@+id/track_selection_dialog_view_pager"
android:layout_width="match_parent"
android:layout_height="200dp">
<com.google.android.material.tabs.TabLayout
android:id="@+id/track_selection_dialog_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"
app:tabMode="fixed" />
</androidx.viewpager.widget.ViewPager>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/track_selection_dialog_ok_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:text="@android:string/ok"
android:textColor="@color/white" />
<TextView
android:id="@+id/track_selection_dialog_cancel_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:text="@android:string/cancel"
android:textColor="@color/white" />
</LinearLayout>
</LinearLayout>

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/black_50"
android:gravity="center"
android:orientation="vertical"
android:padding="@dimen/exo_styled_controls_padding">
<ImageView
android:layout_width="64dp"
android:layout_height="64dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_vod_error" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textColor="@color/white"
android:textSize="18sp"
tools:text="@string/error_play_format" />
</LinearLayout>

@ -11,6 +11,7 @@
<string name="vod_last">上次看到<xliff:g name="name">%s</xliff:g></string>
<!-- Detail -->
<string name="detail_title"><xliff:g name="name">%s</xliff:g><xliff:g name="name">%s</xliff:g></string>
<string name="detail_site">站源:<xliff:g name="name">%s</xliff:g></string>
<string name="detail_year">年份:<xliff:g name="name">%s</xliff:g></string>
<string name="detail_area">地区:<xliff:g name="name">%s</xliff:g></string>
@ -26,6 +27,7 @@
<string name="play_ready">准备播放:<xliff:g name="name">%s</xliff:g></string>
<string name="play_replay">重播</string>
<string name="play_reset">重置</string>
<string name="play_tracks">轨道</string>
<string name="play_oped">片头片尾</string>
<string name="play_reverse">倒序</string>
<string name="play_forward"></string>

@ -11,6 +11,7 @@
<string name="vod_last">上次看到<xliff:g name="name">%s</xliff:g></string>
<!-- Detail -->
<string name="detail_title"><xliff:g name="name">%s</xliff:g><xliff:g name="name">%s</xliff:g></string>
<string name="detail_site">站源:<xliff:g name="name">%s</xliff:g></string>
<string name="detail_year">年份:<xliff:g name="name">%s</xliff:g></string>
<string name="detail_area">地區:<xliff:g name="name">%s</xliff:g></string>
@ -26,6 +27,7 @@
<string name="play_ready">準備播放:<xliff:g name="name">%s</xliff:g></string>
<string name="play_replay">重播</string>
<string name="play_reset">重置</string>
<string name="play_tracks">軌道</string>
<string name="play_oped">片頭片尾</string>
<string name="play_reverse">倒序</string>
<string name="play_forward"></string>

@ -11,6 +11,7 @@
<string name="vod_last">Last seen <xliff:g name="name">%s</xliff:g></string>
<!-- Detail -->
<string name="detail_title"><xliff:g name="name">%s</xliff:g> : <xliff:g name="name">%s</xliff:g></string>
<string name="detail_site">Site: <xliff:g name="name">%s</xliff:g></string>
<string name="detail_year">Year: <xliff:g name="name">%s</xliff:g></string>
<string name="detail_area">Area: <xliff:g name="name">%s</xliff:g></string>
@ -26,6 +27,7 @@
<string name="play_ready">Ready to play: <xliff:g name="name">%s</xliff:g></string>
<string name="play_replay">Replay</string>
<string name="play_reset">Reset</string>
<string name="play_tracks">Tracks</string>
<string name="play_oped">OP&amp;ED</string>
<string name="play_reverse">Reverse</string>
<string name="play_forward"></string>

Loading…
Cancel
Save