[mobile] support bg play - part 5

pull/142/head
FongMi 3 years ago
parent 80358e0804
commit e20e1c2ffc
  1. 2
      app/src/main/java/com/fongmi/android/tv/bean/Epg.java
  2. 29
      app/src/main/java/com/fongmi/android/tv/player/Players.java
  3. 6
      app/src/main/java/com/fongmi/android/tv/utils/ImgUtil.java
  4. 2
      app/src/main/res/values-zh-rCN/strings.xml
  5. 2
      app/src/main/res/values-zh-rTW/strings.xml
  6. 2
      app/src/main/res/values/strings.xml
  7. 2
      app/src/mobile/AndroidManifest.xml
  8. 38
      app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java
  9. 16
      app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java
  10. 8
      ijkplayer/src/main/java/tv/danmaku/ijk/media/player/ui/IjkVideoView.java

@ -97,7 +97,7 @@ public class Epg {
private String format() {
if (getTitle().isEmpty()) return "";
if (getStart().isEmpty() || getEnd().isEmpty()) return ResUtil.getString(R.string.live_epg_now, getTitle());
if (getStart().isEmpty() || getEnd().isEmpty()) return ResUtil.getString(R.string.play_now, getTitle());
return getStart() + " ~ " + getEnd() + " " + getTitle();
}

@ -3,11 +3,12 @@ package com.fongmi.android.tv.player;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.media3.common.MediaMetadata;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.Player;
import androidx.media3.common.util.Util;
@ -22,6 +23,7 @@ import com.fongmi.android.tv.Setting;
import com.fongmi.android.tv.bean.Channel;
import com.fongmi.android.tv.bean.Result;
import com.fongmi.android.tv.bean.Track;
import com.fongmi.android.tv.event.ActionEvent;
import com.fongmi.android.tv.event.ErrorEvent;
import com.fongmi.android.tv.event.PlayerEvent;
import com.fongmi.android.tv.impl.ParseCallback;
@ -47,9 +49,9 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic
public static final int SOFT = 0;
public static final int HARD = 1;
private MediaMetadataCompat metadata;
private MediaSessionCompat session;
private IjkVideoView ijkPlayer;
private MediaMetadata metadata;
private StringBuilder builder;
private Formatter formatter;
private ExoPlayer exoPlayer;
@ -90,7 +92,6 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic
private void createSession(Activity activity) {
session = new MediaSessionCompat(activity, "TV");
session.setSessionActivity(PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass()), Utils.getPendingFlag()));
session.setActive(true);
}
public void set(PlayerView exo, IjkVideoView ijk) {
@ -127,12 +128,10 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic
return session;
}
public MediaMetadata getMetadata() {
return metadata;
}
public void setMetadata(MediaMetadata metadata) {
public void setMetadata(MediaMetadataCompat metadata) {
this.metadata = metadata;
session.setMetadata(metadata);
ActionEvent.update();
}
public int getPlayer() {
@ -279,21 +278,25 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic
public void play() {
if (isExo()) exoPlayer.play();
else if (isIjk()) ijkPlayer.start();
session.setActive(true);
}
public void pause() {
if (isExo()) pauseExo();
else if (isIjk()) pauseIjk();
session.setActive(false);
}
public void stop() {
reset();
if (isExo()) stopExo();
else if (isIjk()) stopIjk();
session.setActive(false);
}
public void release() {
stopParse();
session.release();
if (isExo()) releaseExo();
else if (isIjk()) releaseIjk();
}
@ -450,6 +453,16 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic
ErrorEvent.parse();
}
@Override
public void onEvents(@NonNull Player player, @NonNull Player.Events events) {
session.setPlaybackState(new PlaybackStateCompat.Builder().setState(isPlaying() ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED, getPosition(), getSpeed()).build());
}
@Override
public void onBufferingUpdate(IMediaPlayer mp, int percent) {
session.setPlaybackState(new PlaybackStateCompat.Builder().setState(isPlaying() ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED, getPosition(), getSpeed()).build());
}
@Override
public void onPlayerError(@NonNull PlaybackException error) {
this.errorCode = error.errorCode;

@ -5,7 +5,6 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
@ -43,11 +42,6 @@ public class ImgUtil {
else Glide.with(App.get()).load(getUrl(url)).error(error).dontAnimate().into(target);
}
public static void load(Uri uri, int error, CustomTarget<Bitmap> target) {
if (uri == null || uri.toString().isEmpty()) target.onLoadFailed(ResUtil.getDrawable(error));
else Glide.with(App.get()).asBitmap().load(getUrl(uri.toString())).error(error).dontAnimate().into(target);
}
public static void load(String url, ImageView view, ImageView.ScaleType scaleType) {
view.setScaleType(scaleType);
if (TextUtils.isEmpty(url)) view.setImageResource(R.drawable.ic_img_error);

@ -10,7 +10,6 @@
<!-- Live -->
<string name="live_pass">密码</string>
<string name="live_group">未分类</string>
<string name="live_epg_now">正在播放:<xliff:g name="name">%s</xliff:g></string>
<string name="live_line">线路 <xliff:g name="name">%s</xliff:g></string>
<!-- Detail -->
@ -47,6 +46,7 @@
<string name="play_track_video">视轨</string>
<string name="play_forward_hint">已切换正序播放</string>
<string name="play_backward_hint">已切换倒序播放</string>
<string name="play_now">正在播放:<xliff:g name="name">%s</xliff:g></string>
<string name="play_ready">准备播放:<xliff:g name="name">%s</xliff:g></string>
<string name="play_switch_parse">正在切换解析至「<xliff:g name="name">%s</xliff:g></string>
<string name="play_switch_flag">正在切换线路至「<xliff:g name="name">%s</xliff:g></string>

@ -10,7 +10,6 @@
<!-- Live -->
<string name="live_pass">密碼</string>
<string name="live_group">未分類</string>
<string name="live_epg_now">正在播放:<xliff:g name="name">%s</xliff:g></string>
<string name="live_line">來源 <xliff:g name="name">%s</xliff:g></string>
<!-- Detail -->
@ -47,6 +46,7 @@
<string name="play_track_video">視軌</string>
<string name="play_forward_hint">已切換正序播放</string>
<string name="play_backward_hint">已切換倒序播放</string>
<string name="play_now">正在播放:<xliff:g name="name">%s</xliff:g></string>
<string name="play_ready">準備播放:<xliff:g name="name">%s</xliff:g></string>
<string name="play_switch_parse">正在切换解析至「<xliff:g name="name">%s</xliff:g></string>
<string name="play_switch_flag">正在切換線路至「<xliff:g name="name">%s</xliff:g></string>

@ -10,7 +10,6 @@
<!-- Live -->
<string name="live_pass">Pass</string>
<string name="live_group">Group</string>
<string name="live_epg_now">Playing: <xliff:g name="name">%s</xliff:g></string>
<string name="live_line">Line <xliff:g name="name">%s</xliff:g></string>
<!-- Detail -->
@ -47,6 +46,7 @@
<string name="play_track_video">Video</string>
<string name="play_forward_hint">Normal play switched</string>
<string name="play_backward_hint">Reverse play switched</string>
<string name="play_now">Playing: <xliff:g name="name">%s</xliff:g></string>
<string name="play_ready">Ready to play: <xliff:g name="name">%s</xliff:g></string>
<string name="play_switch_parse">Switching parse to <xliff:g name="name">%s</xliff:g></string>
<string name="play_switch_flag">Switching flag to <xliff:g name="name">%s</xliff:g></string>

@ -132,7 +132,7 @@
<service
android:name=".service.PlaybackService"
android:exported="false"
android:exported="true"
android:foregroundServiceType="mediaPlayback">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService" />

@ -5,21 +5,23 @@ import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.net.Uri;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.media.MediaMetadataCompat;
import android.view.View;
import androidx.annotation.Dimension;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ShareCompat;
import androidx.lifecycle.ViewModelProvider;
import androidx.media3.common.C;
import androidx.media3.common.MediaMetadata;
import androidx.media3.common.Player;
import androidx.media3.ui.PlayerView;
import androidx.viewbinding.ViewBinding;
import com.bumptech.glide.request.transition.Transition;
import com.fongmi.android.tv.App;
import com.fongmi.android.tv.Constant;
import com.fongmi.android.tv.R;
@ -37,6 +39,7 @@ import com.fongmi.android.tv.event.ActionEvent;
import com.fongmi.android.tv.event.ErrorEvent;
import com.fongmi.android.tv.event.PlayerEvent;
import com.fongmi.android.tv.impl.Callback;
import com.fongmi.android.tv.impl.CustomTarget;
import com.fongmi.android.tv.impl.LiveCallback;
import com.fongmi.android.tv.impl.PassCallback;
import com.fongmi.android.tv.impl.SubtitleCallback;
@ -56,6 +59,7 @@ import com.fongmi.android.tv.ui.custom.dialog.SubtitleDialog;
import com.fongmi.android.tv.ui.custom.dialog.TrackDialog;
import com.fongmi.android.tv.utils.Biometric;
import com.fongmi.android.tv.utils.Clock;
import com.fongmi.android.tv.utils.ImgUtil;
import com.fongmi.android.tv.utils.Notify;
import com.fongmi.android.tv.utils.PiP;
import com.fongmi.android.tv.utils.ResUtil;
@ -447,7 +451,7 @@ public class LiveActivity extends BaseActivity implements CustomKeyDownLive.List
private void showEpg() {
mBinding.widget.play.setText(mChannel.getData().getEpg());
mPlayers.setMetadata(new MediaMetadata.Builder().setTitle(mChannel.getName()).setArtist(mChannel.getData().getEpg()).setArtworkUri(Uri.parse(mChannel.getLogo())).build());
setMetadata();
}
private void setTraffic() {
@ -474,6 +478,23 @@ public class LiveActivity extends BaseActivity implements CustomKeyDownLive.List
this.passCount = 0;
}
private void setArtwork(String url) {
ImgUtil.load(url, R.drawable.radio, new CustomTarget<>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
getExo().setDefaultArtwork(resource);
getIjk().setDefaultArtwork(resource);
setMetadata();
}
@Override
public void onLoadFailed(@Nullable Drawable error) {
getExo().setDefaultArtwork(error);
getIjk().setDefaultArtwork(error);
}
});
}
@Override
public void onItemClick(Group item) {
mGroupAdapter.setSelected(mGroup = item);
@ -490,6 +511,7 @@ public class LiveActivity extends BaseActivity implements CustomKeyDownLive.List
public void onItemClick(Channel item) {
mGroup.setPosition(mChannelAdapter.setSelected(item.group(mGroup)));
mPlayers.setPlayer(getPlayerType(item.getPlayerType()));
setArtwork(item.getLogo());
mChannel = item;
setPlayerView();
showInfo();
@ -642,6 +664,7 @@ public class LiveActivity extends BaseActivity implements CustomKeyDownLive.List
break;
case Player.STATE_READY:
checkRotate();
setMetadata();
resetToggle();
hideProgress();
mPlayers.reset();
@ -674,6 +697,15 @@ public class LiveActivity extends BaseActivity implements CustomKeyDownLive.List
mBinding.control.action.video.setVisibility(visible && mPlayers.haveTrack(C.TRACK_TYPE_VIDEO) ? View.VISIBLE : View.GONE);
}
private void setMetadata() {
MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mChannel.getName());
builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, mChannel.getData().getEpg());
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, getIjk().getDefaultArtwork());
builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mPlayers.getDuration());
mPlayers.setMetadata(builder.build());
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onErrorEvent(ErrorEvent event) {
if (mPlayers.addRetry() > event.getRetry()) checkError(event);

@ -10,6 +10,7 @@ import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.media.MediaMetadataCompat;
import android.text.Html;
import android.text.TextUtils;
import android.view.MotionEvent;
@ -27,7 +28,6 @@ import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.media3.common.C;
import androidx.media3.common.MediaMetadata;
import androidx.media3.common.Player;
import androidx.media3.ui.PlayerView;
import androidx.recyclerview.widget.RecyclerView;
@ -484,11 +484,10 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
private void getPlayer(Flag flag, Episode episode, boolean replay) {
mBinding.control.title.setText(getString(R.string.detail_title, mBinding.name.getText(), episode.getName()));
mPlayers.setMetadata(new MediaMetadata.Builder().setTitle(mHistory.getVodName()).setArtist(episode.getName()).setArtworkUri(Uri.parse(mHistory.getVodPic())).build());
mViewModel.playerContent(getKey(), flag.getFlag(), episode.getUrl());
updateHistory(episode, replay);
ActionEvent.update();
showProgress();
setMetadata();
hidePreview();
setUrl(null);
}
@ -926,6 +925,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
getExo().setDefaultArtwork(resource);
getIjk().setDefaultArtwork(resource);
showPreview(resource);
setMetadata();
}
@Override
@ -1056,6 +1056,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
case Player.STATE_READY:
stopSearch();
checkRotate();
setMetadata();
resetToggle();
hideProgress();
mPlayers.reset();
@ -1105,6 +1106,15 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
}
}
private void setMetadata() {
MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mHistory == null ? getName() : mHistory.getVodName());
builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, mEpisodeAdapter.getItemCount() == 0 ? "" : getString(R.string.play_now, getEpisode().getName()));
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, getIjk().getDefaultArtwork());
builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mPlayers.getDuration());
mPlayers.setMetadata(builder.build());
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onErrorEvent(ErrorEvent event) {
if (mPlayers.addRetry() > event.getRetry()) checkError(event);

@ -2,6 +2,8 @@ package tv.danmaku.ijk.media.player.ui;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.MediaPlayer;
@ -415,6 +417,10 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
}
}
public Bitmap getDefaultArtwork() {
return ((BitmapDrawable) mDefaultArtwork).getBitmap();
}
private void updateForCurrentTrackSelections() {
if (mPlayer == null || mPlayer.getTrackInfo().isEmpty()) return;
int select = getSelectedTrack(ITrackInfo.MEDIA_TRACK_TYPE_VIDEO);
@ -524,11 +530,13 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
@Override
public void onBufferingUpdate(IMediaPlayer mp, int percent) {
mListener.onBufferingUpdate(mp, percent);
mCurrentBufferPercentage = percent;
}
@Override
public void onBufferingUpdate(IMediaPlayer mp, long position) {
mListener.onBufferingUpdate(mp, position);
mCurrentBufferPosition = position;
}

Loading…
Cancel
Save