Support ijkplayer - part 4

pull/123/head
FongMi 3 years ago
parent cdc344049f
commit 77e741afe4
  1. 6
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/DetailActivity.java
  2. 113
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/LiveActivity.java
  3. 8
      app/src/leanback/res/layout/activity_live.xml
  4. 173
      app/src/leanback/res/layout/view_control_live.xml
  5. 0
      app/src/leanback/res/layout/view_control_vod.xml
  6. 165
      app/src/leanback/res/layout/view_controller_live.xml
  7. 5
      app/src/leanback/res/values/styles.xml
  8. 2
      app/src/main/java/com/fongmi/android/tv/bean/Live.java
  9. 37
      app/src/main/java/com/fongmi/android/tv/player/IjkUtil.java
  10. 65
      app/src/main/java/com/fongmi/android/tv/player/Players.java
  11. 8
      app/src/main/java/com/fongmi/android/tv/utils/Prefers.java
  12. 5
      app/src/main/res/values-zh-rCN/strings.xml
  13. 5
      app/src/main/res/values-zh-rTW/strings.xml
  14. 5
      app/src/main/res/values/strings.xml
  15. 1
      ijkplayer/build.gradle
  16. 113
      ijkplayer/src/main/java/tv/danmaku/ijk/media/player/ui/IjkVideoView.java

@ -28,7 +28,7 @@ import com.fongmi.android.tv.bean.Part;
import com.fongmi.android.tv.bean.Result;
import com.fongmi.android.tv.bean.Vod;
import com.fongmi.android.tv.databinding.ActivityDetailBinding;
import com.fongmi.android.tv.databinding.ViewControllerVodBinding;
import com.fongmi.android.tv.databinding.ViewControlVodBinding;
import com.fongmi.android.tv.db.AppDatabase;
import com.fongmi.android.tv.event.PlayerEvent;
import com.fongmi.android.tv.event.RefreshEvent;
@ -68,7 +68,7 @@ import okhttp3.Response;
public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Listener, ArrayPresenter.OnClickListener, Clock.Callback {
private ActivityDetailBinding mBinding;
private ViewControllerVodBinding mControl;
private ViewControlVodBinding mControl;
private ViewGroup.LayoutParams mFrameParams;
private ArrayObjectAdapter mFlagAdapter;
private ArrayObjectAdapter mArrayAdapter;
@ -128,7 +128,7 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
@Override
protected ViewBinding getBinding() {
mBinding = ActivityDetailBinding.inflate(getLayoutInflater());
mControl = ViewControllerVodBinding.bind(getPlayerView().findViewById(com.google.android.exoplayer2.ui.R.id.exo_controller));
mControl = ViewControlVodBinding.bind(getPlayerView().findViewById(com.google.android.exoplayer2.ui.R.id.exo_controller));
return mBinding;
}

@ -23,7 +23,6 @@ import com.fongmi.android.tv.bean.Group;
import com.fongmi.android.tv.bean.Keep;
import com.fongmi.android.tv.bean.Live;
import com.fongmi.android.tv.databinding.ActivityLiveBinding;
import com.fongmi.android.tv.databinding.ViewControllerLiveBinding;
import com.fongmi.android.tv.event.PlayerEvent;
import com.fongmi.android.tv.impl.LiveCallback;
import com.fongmi.android.tv.impl.PassCallback;
@ -59,11 +58,11 @@ import java.util.Locale;
import okhttp3.Call;
import okhttp3.Response;
import tv.danmaku.ijk.media.player.ui.IjkVideoView;
public class LiveActivity extends BaseActivity implements GroupPresenter.OnClickListener, ChannelPresenter.OnClickListener, CustomKeyDownLive.Listener, CustomLiveListView.Callback, PassCallback, LiveCallback {
private ActivityLiveBinding mBinding;
private ViewControllerLiveBinding mControl;
private ArrayObjectAdapter mChannelAdapter;
private ArrayObjectAdapter mGroupAdapter;
private SimpleDateFormat mFormatDate;
@ -86,10 +85,14 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
if (!LiveConfig.isEmpty()) activity.startActivity(new Intent(activity, LiveActivity.class));
}
private StyledPlayerView getPlayerView() {
private StyledPlayerView getExo() {
return Prefers.getRender() == 0 ? mBinding.surface : mBinding.texture;
}
private IjkVideoView getIjk() {
return mBinding.ijk;
}
private Group getKeep() {
return (Group) mGroupAdapter.get(0);
}
@ -104,9 +107,7 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
@Override
protected ViewBinding getBinding() {
mBinding = ActivityLiveBinding.inflate(getLayoutInflater());
mControl = ViewControllerLiveBinding.bind(getPlayerView().findViewById(com.google.android.exoplayer2.ui.R.id.exo_controller));
return mBinding;
return mBinding = ActivityLiveBinding.inflate(getLayoutInflater());
}
@Override
@ -131,12 +132,13 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
protected void initEvent() {
mBinding.group.setListener(this);
mBinding.channel.setListener(this);
mControl.home.setOnClickListener(view -> onHome());
mControl.scale.setOnClickListener(view -> onScale());
mControl.speed.setOnClickListener(view -> onSpeed());
mControl.tracks.setOnClickListener(view -> onTracks());
mControl.line.setOnClickListener(view -> nextLine(false));
mControl.speed.setOnLongClickListener(view -> onSpeedLong());
mBinding.control.home.setOnClickListener(view -> onHome());
mBinding.control.scale.setOnClickListener(view -> onScale());
mBinding.control.speed.setOnClickListener(view -> onSpeed());
mBinding.control.tracks.setOnClickListener(view -> onTracks());
mBinding.control.player.setOnClickListener(view -> onPlayer());
mBinding.control.line.setOnClickListener(view -> nextLine(false));
mBinding.control.speed.setOnLongClickListener(view -> onSpeedLong());
mBinding.group.addOnChildViewHolderSelectedListener(new OnChildViewHolderSelectedListener() {
@Override
public void onChildViewHolderSelected(@NonNull RecyclerView parent, @Nullable RecyclerView.ViewHolder child, int position, int subposition) {
@ -166,14 +168,20 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
}
private void setVideoView() {
getPlayerView().setPlayer(mPlayers.exo());
getPlayerView().setVisibility(View.VISIBLE);
getPlayerView().setResizeMode(Prefers.getLiveScale());
getPlayerView().setOnClickListener(view -> onToggle());
getPlayerView().setOnLongClickListener(view -> onLongPress());
mControl.home.setVisibility(LiveConfig.isOnly() ? View.GONE : View.VISIBLE);
mControl.scale.setText(ResUtil.getStringArray(R.array.select_scale)[Prefers.getLiveScale()]);
mControl.speed.setText(mPlayers.getSpeed());
getExo().setPlayer(mPlayers.exo());
getExo().setResizeMode(Prefers.getLiveScale());
getExo().setOnClickListener(view -> onToggle());
getExo().setOnLongClickListener(view -> onLongPress());
getIjk().setPlayer(mPlayers.ijk());
getIjk().setRender(Prefers.getRender());
getIjk().setResizeMode(Prefers.getLiveScale());
getIjk().setOnClickListener(view -> onToggle());
getIjk().setOnLongClickListener(view -> onLongPress());
getExo().setVisibility(Prefers.getPlayer() == 0 ? View.VISIBLE : View.GONE);
getIjk().setVisibility(Prefers.getPlayer() == 1 ? View.VISIBLE : View.GONE);
mBinding.control.home.setVisibility(LiveConfig.isOnly() ? View.GONE : View.VISIBLE);
mBinding.control.scale.setText(ResUtil.getStringArray(R.array.select_scale)[Prefers.getLiveScale()]);
mBinding.control.speed.setText(mPlayers.getSpeed());
}
private void setGroup(Live home) {
@ -182,7 +190,7 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
for (Group group : home.getGroups()) (group.isHidden() ? mHides : items).add(group);
mGroupAdapter.setItems(items, null);
setPosition(LiveConfig.get().find(items));
mControl.home.setText(home.getName());
mBinding.control.home.setText(home.getName());
hideProgress();
}
@ -223,39 +231,46 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
}
private void onToggle() {
getPlayerView().hideController();
if (isVisible(mBinding.recycler)) hideUI();
else showUI();
hideControl();
hideInfo();
}
private void onHome() {
App.post(() -> getPlayerView().hideController(), 150);
LiveDialog.create(this).show();
hideControl();
}
private void onScale() {
int scale = getPlayerView().getResizeMode();
getPlayerView().setResizeMode(scale = scale == 4 ? 0 : scale + 1);
mControl.scale.setText(ResUtil.getStringArray(R.array.select_scale)[scale]);
Prefers.putLiveScale(scale);
//int scale = getPlayerView().getResizeMode();
// getPlayerView().setResizeMode(scale = scale == 4 ? 0 : scale + 1);
//mBinding.control.scale.setText(ResUtil.getStringArray(R.array.select_scale)[scale]);
//Prefers.putLiveScale(scale);
}
private void onSpeed() {
mPlayers.addSpeed();
mControl.speed.setText(mPlayers.getSpeed());
mBinding.control.speed.setText(mPlayers.getSpeed());
}
private boolean onSpeedLong() {
mPlayers.toggleSpeed();
mControl.speed.setText(mPlayers.getSpeed());
mBinding.control.speed.setText(mPlayers.getSpeed());
return true;
}
private void onTracks() {
App.post(() -> getPlayerView().hideController(), 150);
TrackSelectionDialog.createForPlayer(mPlayers.exo(), dialog -> {
}).show(getSupportFragmentManager(), "tracks");
hideControl();
}
private void onPlayer() {
CharSequence[] array = ResUtil.getStringArray(R.array.select_player);
int index = Prefers.getPlayer();
Prefers.putPlayer(index = index == array.length - 1 ? 0 : ++index);
mBinding.control.player.setText(array[index]);
}
private void hideUI() {
@ -280,6 +295,14 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
mBinding.widget.progress.getRoot().setVisibility(View.GONE);
}
private void showControl() {
mBinding.control.getRoot().setVisibility(View.VISIBLE);
}
private void hideControl() {
mBinding.control.getRoot().setVisibility(View.GONE);
}
private void hideInfo() {
mBinding.widget.info.setVisibility(View.GONE);
}
@ -291,7 +314,7 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
}
private void showEpg() {
mControl.play.setText(mChannel.getData().getEpg());
mBinding.control.play.setText(mChannel.getData().getEpg());
mBinding.widget.play.setText(mChannel.getData().getEpg());
}
@ -354,13 +377,13 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
private void setInfo() {
mChannel.loadLogo(mBinding.widget.logo);
mControl.name.setText(mChannel.getName());
mControl.line.setText(mChannel.getLineText());
mControl.number.setText(mChannel.getNumber());
mBinding.control.name.setText(mChannel.getName());
mBinding.control.line.setText(mChannel.getLineText());
mBinding.control.number.setText(mChannel.getNumber());
mBinding.widget.name.setText(mChannel.getName());
mBinding.widget.line.setText(mChannel.getLineText());
mBinding.widget.number.setText(mChannel.getNumber());
mControl.line.setVisibility(mChannel.getLineVisible());
mBinding.control.line.setVisibility(mChannel.getLineVisible());
mBinding.widget.logo.setVisibility(mChannel.getLogoVisible());
mBinding.widget.line.setVisibility(mChannel.getLineVisible());
checkEpg();
@ -431,7 +454,7 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
public boolean dispatchKeyEvent(KeyEvent event) {
if (Utils.isMenuKey(event)) onLongPress();
if (mGroup == null || mChannel == null) return super.dispatchKeyEvent(event);
else if (isGone(mBinding.recycler) && !getPlayerView().isControllerFullyVisible() && mKeyDown.hasEvent(event)) return mKeyDown.onKeyDown(event);
else if (isGone(mBinding.recycler) && !isVisible(mBinding.control.getRoot()) && mKeyDown.hasEvent(event)) return mKeyDown.onKeyDown(event);
return super.dispatchKeyEvent(event);
}
@ -455,7 +478,7 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
@Override
public void onSeeking(int time) {
if (!mPlayers.isVod() || !mChannel.isOnly()) return;
mBinding.widget.exoDuration.setText(mControl.exoDuration.getText());
mBinding.widget.exoDuration.setText(mBinding.control.duration.getText());
mBinding.widget.exoPosition.setText(mPlayers.getTime(time));
mBinding.widget.action.setImageResource(time > 0 ? R.drawable.ic_forward : R.drawable.ic_rewind);
mBinding.widget.center.setVisibility(View.VISIBLE);
@ -501,10 +524,10 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
@Override
public boolean onLongPress() {
if (isVisible(mControl.home)) mControl.home.requestFocus();
else if (isVisible(mControl.line)) mControl.line.requestFocus();
else mControl.speed.requestFocus();
getPlayerView().showController();
if (isVisible(mBinding.control.home)) mBinding.control.home.requestFocus();
else if (isVisible(mBinding.control.line)) mBinding.control.line.requestFocus();
else mBinding.control.speed.requestFocus();
showControl();
hideInfo();
hideUI();
return true;
@ -525,9 +548,9 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
@Override
public void setLive(Live item) {
getPlayerView().hideController();
LiveConfig.get().setHome(item);
mHides.clear();
hideControl();
getLive();
}
@ -546,7 +569,7 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
hideProgress();
mPlayers.reset();
App.removeCallbacks(mR4);
TrackSelectionDialog.setVisible(mPlayers.exo(), mControl.tracks);
TrackSelectionDialog.setVisible(mPlayers.exo(), mBinding.control.tracks);
break;
case Player.STATE_ENDED:
onKeyDown();
@ -585,8 +608,8 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
@Override
public void onBackPressed() {
if (getPlayerView().isControllerFullyVisible()) {
getPlayerView().hideController();
if (isVisible(mBinding.control.getRoot())) {
hideControl();
} else if (isVisible(mBinding.widget.info)) {
hideInfo();
} else if (isVisible(mBinding.recycler)) {

@ -35,6 +35,14 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
android:id="@+id/control"
layout="@layout/view_control_live"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:visibility="gone" />
<LinearLayout
android:id="@+id/recycler"
android:layout_width="wrap_content"

@ -0,0 +1,173 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/exo_bottom_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/shape_controller"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:textColor="@color/grey_800"
android:textSize="18sp"
tools:text="005" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:maxEms="30"
android:singleLine="true"
android:textColor="@color/grey_800"
android:textSize="18sp"
tools:text="民視" />
<TextView
android:id="@+id/play"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginEnd="12dp"
android:layout_weight="1"
android:singleLine="true"
android:textColor="@color/grey_800"
android:textSize="18sp"
tools:text="正在播放:食神" />
<TextView
android:id="@+id/home"
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:textColor="@color/white"
android:textSize="14sp"
tools:text="首頁" />
<TextView
android:id="@+id/line"
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:textColor="@color/white"
android:textSize="14sp"
android:visibility="gone"
tools:text="來源 1"
tools:visibility="visible" />
<TextView
android:id="@+id/player"
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:textColor="@color/white"
android:textSize="14sp"
tools:text="EXO" />
<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: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:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
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_marginStart="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:text="@string/play_tracks"
android:textColor="@color/white"
android:textSize="14sp"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/grey_700"
android:textSize="16sp"
tools:text="00:00:00" />
<com.google.android.exoplayer2.ui.DefaultTimeBar
android:id="@+id/progress"
android:layout_width="0dp"
android:layout_height="26dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_weight="1"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusLeft="@+id/progress"
android:nextFocusRight="@+id/progress"
android:nextFocusDown="@+id/progress"
app:buffered_color="@color/grey_700"
app:played_color="@color/blue_700"
app:scrubber_color="@color/blue_500"
app:unplayed_color="@color/grey_500" />
<TextView
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/grey_700"
android:textSize="16sp"
tools:text="00:00:00" />
</LinearLayout>
</LinearLayout>

@ -1,165 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:id="@+id/exo_bottom_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/shape_controller"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:textColor="@color/grey_800"
android:textSize="18sp"
tools:text="005" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:maxEms="30"
android:singleLine="true"
android:textColor="@color/grey_800"
android:textSize="18sp"
tools:text="民視" />
<TextView
android:id="@+id/play"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginEnd="12dp"
android:layout_weight="1"
android:singleLine="true"
android:textColor="@color/grey_800"
android:textSize="18sp"
tools:text="正在播放:食神" />
<TextView
android:id="@+id/home"
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:textColor="@color/white"
android:textSize="14sp"
tools:text="首頁" />
<TextView
android:id="@+id/line"
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:textColor="@color/white"
android:textSize="14sp"
android:visibility="gone"
tools:text="來源 1"
tools:visibility="visible" />
<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: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:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
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_marginStart="12dp"
android:background="@drawable/selector_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:text="@string/play_tracks"
android:textColor="@color/white"
android:textSize="14sp"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout>
<LinearLayout
android:id="@id/exo_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@id/exo_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/grey_700"
android:textSize="16sp"
tools:text="00:00:00" />
<com.google.android.exoplayer2.ui.DefaultTimeBar
android:id="@id/exo_progress"
android:layout_width="0dp"
android:layout_height="26dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_weight="1"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusLeft="@id/exo_progress"
android:nextFocusRight="@id/exo_progress"
android:nextFocusDown="@id/exo_progress"
app:buffered_color="@color/grey_700"
app:played_color="@color/blue_700"
app:scrubber_color="@color/blue_500"
app:unplayed_color="@color/grey_500" />
<TextView
android:id="@id/exo_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/grey_700"
android:textSize="16sp"
tools:text="00:00:00" />
</LinearLayout>
</LinearLayout>
</merge>

@ -25,18 +25,17 @@
<item name="use_controller">false</item>
<item name="animation_enabled">false</item>
<item name="default_artwork">@drawable/radio</item>
<item name="controller_layout_id">@layout/view_controller_vod</item>
<item name="controller_layout_id">@layout/view_control_vod</item>
</style>
<style name="LivePlayerStyle">
<item name="auto_show">false</item>
<item name="resize_mode">fit</item>
<item name="use_artwork">true</item>
<item name="use_controller">true</item>
<item name="use_controller">false</item>
<item name="animation_enabled">false</item>
<item name="default_artwork">@drawable/radio</item>
<item name="keep_content_on_player_reset">true</item>
<item name="controller_layout_id">@layout/view_controller_live</item>
</style>
</resources>

@ -104,7 +104,7 @@ public class Live {
}
public Live check() {
boolean proxy = getGroup().equals("redirect") && getChannels().size() > 0 && getChannels().get(0).getUrls().size() > 0 && getChannels().get(0).getUrls().get(0).startsWith("proxy");
boolean proxy = getGroup().equals("redirect") && getChannels().size() > 0 && getChannels().get(0).getUrls().size() > 0 && getChannels().get(0).getUrls().get(0).startsWith("proxy") && getChannels().get(0).getUrls().get(0).contains("ext=");
if (proxy) this.url = getChannels().get(0).getUrls().get(0).split("ext=")[1];
if (proxy) this.name = getChannels().get(0).getName();
return this;

@ -0,0 +1,37 @@
package com.fongmi.android.tv.player;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
public class IjkUtil {
public static IjkMediaPlayer createPlayer() {
int player = IjkMediaPlayer.OPT_CATEGORY_PLAYER;
int codec = IjkMediaPlayer.OPT_CATEGORY_CODEC;
int format = IjkMediaPlayer.OPT_CATEGORY_FORMAT;
IjkMediaPlayer ijkPlayer = new IjkMediaPlayer();
ijkPlayer.setOption(codec, "skip_loop_filter", 48);
ijkPlayer.setOption(format, "probesize", 1024 * 800);
ijkPlayer.setOption(player, "max-buffer-size", 1024 * 800);
ijkPlayer.setOption(format, "analyzeduration", 30 * 1000 * 1000);
ijkPlayer.setOption(format, "analyzemaxduration", 30 * 1000 * 1000);
ijkPlayer.setOption(player, "soundtouch", 1);
ijkPlayer.setOption(format, "flush_packets", 1);
ijkPlayer.setOption(player, "packet-buffering", 0);
ijkPlayer.setOption(player, "reconnect", 1);
ijkPlayer.setOption(player, "framedrop", 1);
ijkPlayer.setOption(player, "max-fps", 60);
ijkPlayer.setOption(player, "enable-accurate-seek", 0);
ijkPlayer.setOption(format, "fflags", "fastseek");
ijkPlayer.setOption(format, "dns_cache_clear", 1);
ijkPlayer.setOption(format, "timeout", 30 * 1000 * 1000);
ijkPlayer.setOption(format, "rtsp_transport", "tcp");
ijkPlayer.setOption(format, "rtsp_flags", "prefer_tcp");
ijkPlayer.setOption(format, "buffer_size", 1024 * 800);
ijkPlayer.setOption(format, "infbuf", 1);
ijkPlayer.setOption(player, "videotoolbox", 0);
ijkPlayer.setOption(player, "mediacodec", 0);
ijkPlayer.setOption(player, "mediacodec-auto-rotate", 0);
ijkPlayer.setOption(player, "mediacodec-handle-resolution-change", 0);
return ijkPlayer;
}
}

@ -22,12 +22,16 @@ import java.util.Formatter;
import java.util.Locale;
import java.util.Map;
public class Players implements Player.Listener, AnalyticsListener, ParseTask.Callback {
import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IMediaPlayer.OnErrorListener, IMediaPlayer.OnPreparedListener, IMediaPlayer.OnCompletionListener, AnalyticsListener, ParseTask.Callback {
private IjkMediaPlayer ijkPlayer;
private StringBuilder builder;
private Formatter formatter;
private ExoPlayer exoPlayer;
private ParseTask parseTask;
private ExoPlayer exoPlayer;
private int errorCode;
private int retry;
@ -46,12 +50,21 @@ public class Players implements Player.Listener, AnalyticsListener, ParseTask.Ca
exoPlayer.addAnalyticsListener(this);
exoPlayer.setPlayWhenReady(true);
exoPlayer.addListener(this);
ijkPlayer = IjkUtil.createPlayer();
ijkPlayer.setOnInfoListener(this);
ijkPlayer.setOnErrorListener(this);
ijkPlayer.setOnPreparedListener(this);
ijkPlayer.setOnCompletionListener(this);
}
public ExoPlayer exo() {
return exoPlayer;
}
public IjkMediaPlayer ijk() {
return ijkPlayer;
}
public void reset() {
this.errorCode = 0;
this.retry = 0;
@ -179,6 +192,34 @@ public class Players implements Player.Listener, AnalyticsListener, ParseTask.Ca
exoPlayer.prepare();
}
public int getResizeMode() {
return 0;
}
public void setResizeMode() {
}
public void setRender() {
}
public void setPlayer() {
}
public void setVisibility() {
}
public void setOnClickListener() {
}
public void setOnLongClickListener() {
}
@Override
public void onParseSuccess(Map<String, String> headers, String url, String from) {
if (from.length() > 0) Notify.show(ResUtil.getString(R.string.parse_from, from));
@ -205,4 +246,24 @@ public class Players implements Player.Listener, AnalyticsListener, ParseTask.Ca
public void onAudioSinkError(@NonNull EventTime eventTime, @NonNull Exception audioSinkError) {
seekTo(200);
}
@Override
public boolean onInfo(IMediaPlayer mp, int what, int extra) {
return false;
}
@Override
public boolean onError(IMediaPlayer mp, int what, int extra) {
return false;
}
@Override
public void onPrepared(IMediaPlayer mp) {
}
@Override
public void onCompletion(IMediaPlayer mp) {
}
}

@ -67,6 +67,14 @@ public class Prefers {
put("wall", wall);
}
public static int getPlayer() {
return getInt("player", 0);
}
public static void putPlayer(int player) {
put("player", player);
}
public static int getRender() {
return getInt("render", 0);
}

@ -97,6 +97,11 @@
<!-- UNIT -->
<string name="all">全部</string>
<string-array name="select_player">
<item>Exo</item>
<item>Ijk</item>
</string-array>
<string-array name="select_quality">
<item></item>
<item></item>

@ -97,6 +97,11 @@
<!-- UNIT -->
<string name="all">全部</string>
<string-array name="select_player">
<item>Exo</item>
<item>Ijk</item>
</string-array>
<string-array name="select_quality">
<item></item>
<item></item>

@ -97,6 +97,11 @@
<!-- UNIT -->
<string name="all">All</string>
<string-array name="select_player">
<item>Exo</item>
<item>Ijk</item>
</string-array>
<string-array name="select_render">
<item>Surface</item>
<item>Texture</item>

@ -8,6 +8,7 @@ android {
defaultConfig {
minSdk 21
targetSdk 33
ndk { abiFilters "armeabi-v7a" }
}
}

@ -17,8 +17,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import tv.danmaku.ijk.media.player.IMediaPlayer;
@ -40,12 +38,15 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
private static final int STATE_PAUSED = 4;
private static final int STATE_PLAYBACK_COMPLETED = 5;
public static final int RENDER_SURFACE_VIEW = 0;
public static final int RENDER_TEXTURE_VIEW = 1;
private int mCurrentState = STATE_IDLE;
private int mTargetState = STATE_IDLE;
// All the stuff we need for playing and showing a video
private IRenderView.ISurfaceHolder mSurfaceHolder = null;
private IMediaPlayer mMediaPlayer = null;
private IjkMediaPlayer mMediaPlayer = null;
private int mVideoWidth;
private int mVideoHeight;
private int mSurfaceWidth;
@ -90,7 +91,6 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
private void initVideoView(Context context) {
mAppContext = context.getApplicationContext();
initRenders();
mVideoWidth = 0;
mVideoHeight = 0;
setFocusable(true);
@ -105,6 +105,17 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
addView(subtitleDisplay, layoutParams_txt);
}
public void setPlayer(IjkMediaPlayer player) {
mMediaPlayer = player;
mMediaPlayer.setOnPreparedListener(mPreparedListener);
mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
mMediaPlayer.setOnCompletionListener(mCompletionListener);
mMediaPlayer.setOnErrorListener(mErrorListener);
mMediaPlayer.setOnInfoListener(mInfoListener);
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
mMediaPlayer.setOnTimedTextListener(mOnTimedTextListener);
}
public void setRenderView(IRenderView renderView) {
if (mRenderView != null) {
if (mMediaPlayer != null) mMediaPlayer.setDisplay(null);
@ -115,7 +126,6 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
}
if (renderView == null) return;
mRenderView = renderView;
renderView.setAspectRatio(mCurrentAspectRatio);
if (mVideoWidth > 0 && mVideoHeight > 0) renderView.setVideoSize(mVideoWidth, mVideoHeight);
if (mVideoSarNum > 0 && mVideoSarDen > 0) renderView.setVideoSampleAspectRatio(mVideoSarNum, mVideoSarDen);
View renderUIView = mRenderView.getView();
@ -134,7 +144,6 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
texture.getSurfaceHolder().bindToMediaPlayer(mMediaPlayer);
texture.setVideoSize(mMediaPlayer.getVideoWidth(), mMediaPlayer.getVideoHeight());
texture.setVideoSampleAspectRatio(mMediaPlayer.getVideoSarNum(), mMediaPlayer.getVideoSarDen());
texture.setAspectRatio(mCurrentAspectRatio);
}
setRenderView(texture);
break;
@ -144,6 +153,10 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
}
}
public void setResizeMode(int resizeMode) {
if (mRenderView != null) mRenderView.setAspectRatio(resizeMode);
}
public void setVideoPath(String path) {
setVideoURI(Uri.parse(path));
}
@ -179,14 +192,6 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
AudioManager am = (AudioManager) mAppContext.getSystemService(Context.AUDIO_SERVICE);
am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
try {
mMediaPlayer = createPlayer();
mMediaPlayer.setOnPreparedListener(mPreparedListener);
mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
mMediaPlayer.setOnCompletionListener(mCompletionListener);
mMediaPlayer.setOnErrorListener(mErrorListener);
mMediaPlayer.setOnInfoListener(mInfoListener);
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
mMediaPlayer.setOnTimedTextListener(mOnTimedTextListener);
mCurrentBufferPercentage = 0;
mMediaPlayer.setDataSource(mAppContext, mUri, mHeaders);
bindSurfaceHolder(mMediaPlayer, mSurfaceHolder);
@ -495,84 +500,4 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
public int getAudioSessionId() {
return 0;
}
private static final int[] s_allAspectRatio = {
IRenderView.AR_ASPECT_WRAP_CONTENT,
IRenderView.AR_16_9_FIT_PARENT,
IRenderView.AR_4_3_FIT_PARENT,
IRenderView.AR_ASPECT_FIT_PARENT,
IRenderView.AR_ASPECT_FILL_PARENT,
};
private int mCurrentAspectRatioIndex = 0;
private int mCurrentAspectRatio = s_allAspectRatio[0];
public int toggleAspectRatio() {
mCurrentAspectRatioIndex++;
mCurrentAspectRatioIndex %= s_allAspectRatio.length;
mCurrentAspectRatio = s_allAspectRatio[mCurrentAspectRatioIndex];
if (mRenderView != null) mRenderView.setAspectRatio(mCurrentAspectRatio);
return mCurrentAspectRatio;
}
public static final int RENDER_SURFACE_VIEW = 1;
public static final int RENDER_TEXTURE_VIEW = 2;
private final List<Integer> mAllRenders = new ArrayList<>();
private int mCurrentRenderIndex = 0;
private int mCurrentRender = RENDER_SURFACE_VIEW;
private void initRenders() {
mAllRenders.clear();
mAllRenders.add(RENDER_SURFACE_VIEW);
mAllRenders.add(RENDER_TEXTURE_VIEW);
mCurrentRender = mAllRenders.get(mCurrentRenderIndex);
setRender(mCurrentRender);
}
public int toggleRender() {
mCurrentRenderIndex++;
mCurrentRenderIndex %= mAllRenders.size();
mCurrentRender = mAllRenders.get(mCurrentRenderIndex);
setRender(mCurrentRender);
return mCurrentRender;
}
public int togglePlayer() {
if (mMediaPlayer != null) mMediaPlayer.release();
if (mRenderView != null) mRenderView.getView().invalidate();
openVideo();
return 0;
}
public IMediaPlayer createPlayer() {
IjkMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_SILENT);
IjkMediaPlayer ijkMediaPlayer = new IjkMediaPlayer();
int player = IjkMediaPlayer.OPT_CATEGORY_PLAYER;
int codec = IjkMediaPlayer.OPT_CATEGORY_CODEC;
int format = IjkMediaPlayer.OPT_CATEGORY_FORMAT;
ijkMediaPlayer.setOption(codec, "skip_loop_filter", 48);
ijkMediaPlayer.setOption(format, "probesize", 1024 * 800);
ijkMediaPlayer.setOption(player, "max-buffer-size", 1024 * 800);
ijkMediaPlayer.setOption(format, "analyzeduration", 30 * 1000 * 1000);
ijkMediaPlayer.setOption(format, "analyzemaxduration", 30 * 1000 * 1000);
ijkMediaPlayer.setOption(player, "soundtouch", 1);
ijkMediaPlayer.setOption(format, "flush_packets", 1);
ijkMediaPlayer.setOption(player, "packet-buffering", 0);
ijkMediaPlayer.setOption(player, "reconnect", 1);
ijkMediaPlayer.setOption(player, "framedrop", 1);
ijkMediaPlayer.setOption(player, "max-fps", 60);
ijkMediaPlayer.setOption(player, "enable-accurate-seek", 0);
ijkMediaPlayer.setOption(format, "fflags", "fastseek");
ijkMediaPlayer.setOption(format, "dns_cache_clear", 1);
ijkMediaPlayer.setOption(format, "timeout", 30 * 1000 * 1000);
ijkMediaPlayer.setOption(format, "rtsp_transport", "tcp");
ijkMediaPlayer.setOption(format, "rtsp_flags", "prefer_tcp");
ijkMediaPlayer.setOption(format, "buffer_size", 1024 * 800);
ijkMediaPlayer.setOption(format, "infbuf", 1);
ijkMediaPlayer.setOption(player, "videotoolbox", 0);
ijkMediaPlayer.setOption(player, "mediacodec", 0);
ijkMediaPlayer.setOption(player, "mediacodec-auto-rotate", 0);
ijkMediaPlayer.setOption(player, "mediacodec-handle-resolution-change", 0);
return ijkMediaPlayer;
}
}
Loading…
Cancel
Save