- 外部播放器增加Kodi

- 播放界面选择播放器逻辑优化
pull/50/head
okjackcaptain 3 years ago
parent 1c5dbaf9e5
commit 1584a3e274
  1. 76
      app/src/main/java/com/github/tvbox/osc/player/controller/VodController.java
  2. 106
      app/src/main/java/com/github/tvbox/osc/player/thirdparty/Kodi.java
  3. 13
      app/src/main/java/com/github/tvbox/osc/ui/activity/PlayActivity.java
  4. 25
      app/src/main/java/com/github/tvbox/osc/ui/fragment/ModelSettingFragment.java
  5. 13
      app/src/main/java/com/github/tvbox/osc/ui/fragment/PlayFragment.java
  6. 87
      app/src/main/java/com/github/tvbox/osc/util/PlayerHelper.java

@ -12,16 +12,17 @@ import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.github.tvbox.osc.R;
import com.github.tvbox.osc.api.ApiConfig;
import com.github.tvbox.osc.bean.IJKCode;
import com.github.tvbox.osc.bean.ParseBean;
import com.github.tvbox.osc.player.thirdparty.MXPlayer;
import com.github.tvbox.osc.player.thirdparty.ReexPlayer;
import com.github.tvbox.osc.subtitle.widget.SimpleSubtitleView;
import com.github.tvbox.osc.ui.adapter.ParseAdapter;
import com.github.tvbox.osc.ui.adapter.SelectDialogAdapter;
import com.github.tvbox.osc.ui.dialog.SelectDialog;
import com.github.tvbox.osc.util.HawkConfig;
import com.github.tvbox.osc.util.PlayerHelper;
import com.orhanobut.hawk.Hawk;
@ -33,6 +34,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;
@ -334,29 +336,56 @@ public class VodController extends BaseController {
// myHandle.postDelayed(myRunnable, myHandleSeconds);
try {
int playerType = mPlayerConfig.getInt("pl");
boolean playerVail = false;
do {
playerType++;
if (playerType <= 2) {
playerVail = true;
} else if (playerType == 10) {
playerVail = mxPlayerExist;
} else if (playerType == 11) {
playerVail = reexPlayerExist;
} else if (playerType > 11) {
playerType = 0;
playerVail = true;
int defaultPos = 0;
ArrayList<Integer> players = PlayerHelper.getExistPlayerTypes();
ArrayList<Integer> renders = new ArrayList<>();
for(int p = 0; p<players.size(); p++) {
renders.add(p);
if (players.get(p) == playerType) {
defaultPos = p;
}
} while (!playerVail);
mPlayerConfig.put("pl", playerType);
updatePlayerCfgView();
listener.updatePlayerCfg();
listener.replay(false);
// hideBottom();
}
SelectDialog<Integer> dialog = new SelectDialog<>(mActivity);
dialog.setTip("请选择播放器");
dialog.setAdapter(new SelectDialogAdapter.SelectDialogInterface<Integer>() {
@Override
public void click(Integer value, int pos) {
try {
dialog.cancel();
int thisPlayType = players.get(pos);
if (thisPlayType != playerType) {
mPlayerConfig.put("pl", thisPlayType);
updatePlayerCfgView();
listener.updatePlayerCfg();
listener.replay(false);
mPlayerBtn.requestFocus();
// hideBottom();
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String getDisplay(Integer val) {
Integer playerType = players.get(val);
return PlayerHelper.getPlayerName(playerType);
}
}, new DiffUtil.ItemCallback<Integer>() {
@Override
public boolean areItemsTheSame(@NonNull @NotNull Integer oldItem, @NonNull @NotNull Integer newItem) {
return oldItem.intValue() == newItem.intValue();
}
@Override
public boolean areContentsTheSame(@NonNull @NotNull Integer oldItem, @NonNull @NotNull Integer newItem) {
return oldItem.intValue() == newItem.intValue();
}
}, renders, defaultPos);
dialog.show();
} catch (JSONException e) {
e.printStackTrace();
}
mPlayerBtn.requestFocus();
}
});
mPlayerIJKBtn.setOnClickListener(new OnClickListener() {
@ -506,14 +535,9 @@ public class VodController extends BaseController {
private JSONObject mPlayerConfig = null;
private boolean mxPlayerExist = false;
private boolean reexPlayerExist = false;
public void setPlayerConfig(JSONObject playerCfg) {
this.mPlayerConfig = playerCfg;
updatePlayerCfgView();
mxPlayerExist = MXPlayer.getPackageInfo() != null;
reexPlayerExist = ReexPlayer.getPackageInfo() != null;
}
void updatePlayerCfgView() {

@ -0,0 +1,106 @@
package com.github.tvbox.osc.player.thirdparty;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.util.Log;
import com.github.tvbox.osc.base.App;
import java.util.HashMap;
public class Kodi {
public static final String TAG = "ThirdParty.Kodi";
private static final String PACKAGE_NAME = "org.xbmc.kodi";
private static final String PLAYBACK_ACTIVITY = "org.xbmc.kodi.Splash";
private static class KodiPackageInfo {
final String packageName;
final String activityName;
KodiPackageInfo(String packageName, String activityName) {
this.packageName = packageName;
this.activityName = activityName;
}
}
private static final KodiPackageInfo[] PACKAGES = {
new KodiPackageInfo(PACKAGE_NAME, PLAYBACK_ACTIVITY),
};
/**
* @return null if any Kodi packages not exist.
*/
public static KodiPackageInfo getPackageInfo() {
for (KodiPackageInfo pkg : PACKAGES) {
try {
ApplicationInfo info = App.getInstance().getPackageManager().getApplicationInfo(pkg.packageName, 0);
if (info.enabled)
return pkg;
else
Log.v(TAG, "Kodi package `" + pkg.packageName + "` is disabled.");
} catch (PackageManager.NameNotFoundException ex) {
Log.v(TAG, "Kodi package `" + pkg.packageName + "` does not exist.");
}
}
return null;
}
private static class Subtitle {
final Uri uri;
String name;
String filename;
Subtitle(Uri uri) {
if (uri.getScheme() == null)
throw new IllegalStateException("Scheme is missed for subtitle URI " + uri);
this.uri = uri;
}
Subtitle(String uriStr) {
this(Uri.parse(uriStr));
}
}
public static boolean run(Activity activity, String url, String title, String subtitle, HashMap<String, String> headers) {
KodiPackageInfo packageInfo = getPackageInfo();
if (packageInfo == null)
return false;
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setPackage(packageInfo.packageName);
intent.setClassName(packageInfo.packageName, packageInfo.activityName);
intent.setData(Uri.parse(url));
intent.putExtra("title", title);
intent.putExtra("name", title);
if (headers != null && headers.size() > 0) {
String[] hds = new String[headers.size() * 2];
int idx = 0;
for (String hk : headers.keySet()) {
hds[idx] = hk;
hds[idx + 1] = headers.get(hk).trim();
idx += 2;
}
intent.putExtra("headers", headers);
}
if (subtitle != null && !subtitle.isEmpty()) {
intent.putExtra("subs", subtitle);
}
try {
activity.startActivity(intent);
return true;
} catch (ActivityNotFoundException ex) {
Log.e(TAG, "Can't run Kodi", ex);
return false;
}
}
}

@ -46,8 +46,6 @@ import com.github.tvbox.osc.cache.CacheManager;
import com.github.tvbox.osc.event.RefreshEvent;
import com.github.tvbox.osc.player.MyVideoView;
import com.github.tvbox.osc.player.controller.VodController;
import com.github.tvbox.osc.player.thirdparty.MXPlayer;
import com.github.tvbox.osc.player.thirdparty.ReexPlayer;
import com.github.tvbox.osc.ui.dialog.SearchSubtitleDialog;
import com.github.tvbox.osc.ui.dialog.SubtitleDialog;
import com.github.tvbox.osc.util.AdBlocker;
@ -300,16 +298,7 @@ public class PlayActivity extends BaseActivity {
String playTitle = mVodInfo.name + " " + vs.name;
setTip("调用外部播放器" + PlayerHelper.getPlayerName(playerType) + "进行播放", true, false);
boolean callResult = false;
switch (playerType) {
case 10: {
callResult = MXPlayer.run(PlayActivity.this, url, playTitle, playSubtitle, headers);
break;
}
case 11: {
callResult = ReexPlayer.run(PlayActivity.this, url, playTitle, playSubtitle, headers);
break;
}
}
callResult = PlayerHelper.runExternalPlayer(playerType, PlayActivity.this, url, playTitle, playSubtitle, headers);
setTip("调用外部播放器" + PlayerHelper.getPlayerName(playerType) + (callResult ? "成功" : "失败"), callResult, !callResult);
return;
}

@ -372,24 +372,31 @@ public class ModelSettingFragment extends BaseLazyFragment {
@Override
public void onClick(View v) {
FastClickCheckUtil.check(v);
int defaultPos = Hawk.get(HawkConfig.PLAY_TYPE, 0);
ArrayList<Integer> players = new ArrayList<>();
players.add(0);
players.add(1);
players.add(2);
int playerType = Hawk.get(HawkConfig.PLAY_TYPE, 0);
int defaultPos = 0;
ArrayList<Integer> players = PlayerHelper.getExistPlayerTypes();
ArrayList<Integer> renders = new ArrayList<>();
for(int p = 0; p<players.size(); p++) {
renders.add(p);
if (players.get(p) == playerType) {
defaultPos = p;
}
}
SelectDialog<Integer> dialog = new SelectDialog<>(mActivity);
dialog.setTip("请选择默认播放器");
dialog.setAdapter(new SelectDialogAdapter.SelectDialogInterface<Integer>() {
@Override
public void click(Integer value, int pos) {
Hawk.put(HawkConfig.PLAY_TYPE, value);
tvPlay.setText(PlayerHelper.getPlayerName(value));
Integer thisPlayerType = players.get(pos);
Hawk.put(HawkConfig.PLAY_TYPE, thisPlayerType);
tvPlay.setText(PlayerHelper.getPlayerName(thisPlayerType));
PlayerHelper.init();
}
@Override
public String getDisplay(Integer val) {
return PlayerHelper.getPlayerName(val);
Integer playerType = players.get(val);
return PlayerHelper.getPlayerName(playerType);
}
}, new DiffUtil.ItemCallback<Integer>() {
@Override
@ -401,7 +408,7 @@ public class ModelSettingFragment extends BaseLazyFragment {
public boolean areContentsTheSame(@NonNull @NotNull Integer oldItem, @NonNull @NotNull Integer newItem) {
return oldItem.intValue() == newItem.intValue();
}
}, players, defaultPos);
}, renders, defaultPos);
dialog.show();
}
});

@ -45,8 +45,6 @@ import com.github.tvbox.osc.cache.CacheManager;
import com.github.tvbox.osc.event.RefreshEvent;
import com.github.tvbox.osc.player.MyVideoView;
import com.github.tvbox.osc.player.controller.VodController;
import com.github.tvbox.osc.player.thirdparty.MXPlayer;
import com.github.tvbox.osc.player.thirdparty.ReexPlayer;
import com.github.tvbox.osc.ui.dialog.SearchSubtitleDialog;
import com.github.tvbox.osc.ui.dialog.SubtitleDialog;
import com.github.tvbox.osc.util.AdBlocker;
@ -298,16 +296,7 @@ public class PlayFragment extends BaseLazyFragment {
String playTitle = mVodInfo.name + " " + vs.name;
setTip("调用外部播放器" + PlayerHelper.getPlayerName(playerType) + "进行播放", true, false);
boolean callResult = false;
switch (playerType) {
case 10: {
callResult = MXPlayer.run(requireActivity(), url, playTitle, playSubtitle, headers);
break;
}
case 11: {
callResult = ReexPlayer.run(requireActivity(), url, playTitle, playSubtitle, headers);
break;
}
}
callResult = PlayerHelper.runExternalPlayer(playerType, requireActivity(), url, playTitle, playSubtitle, headers);
setTip("调用外部播放器" + PlayerHelper.getPlayerName(playerType) + (callResult ? "成功" : "失败"), callResult, !callResult);
return;
}

@ -1,16 +1,23 @@
package com.github.tvbox.osc.util;
import android.app.Activity;
import android.content.Context;
import com.github.tvbox.osc.api.ApiConfig;
import com.github.tvbox.osc.bean.IJKCode;
import com.github.tvbox.osc.player.IjkMediaPlayer;
import com.github.tvbox.osc.player.render.SurfaceRenderViewFactory;
import com.github.tvbox.osc.player.thirdparty.Kodi;
import com.github.tvbox.osc.player.thirdparty.MXPlayer;
import com.github.tvbox.osc.player.thirdparty.ReexPlayer;
import com.orhanobut.hawk.Hawk;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import tv.danmaku.ijk.media.player.IjkLibLoader;
import xyz.doikki.videoplayer.exo.ExoMediaPlayerFactory;
import xyz.doikki.videoplayer.player.AndroidMediaPlayerFactory;
@ -139,19 +146,83 @@ public class PlayerHelper {
}
public static String getPlayerName(int playType) {
if (playType == 1) {
return "IJK播放器";
} else if (playType == 2) {
return "Exo播放器";
} else if (playType == 10) {
return "MXPlayer";
} else if (playType == 11) {
return "Reex";
HashMap<Integer, String> playersInfo = getPlayersInfo();
if (playersInfo.containsKey(playType)) {
return playersInfo.get(playType);
} else {
return "系统播放器";
}
}
private static HashMap<Integer, String> mPlayersInfo = null;
public static HashMap<Integer, String> getPlayersInfo() {
if (mPlayersInfo == null) {
HashMap<Integer, String> playersInfo = new HashMap<>();
playersInfo.put(0, "系统播放器");
playersInfo.put(1, "IJK播放器");
playersInfo.put(2, "Exo播放器");
playersInfo.put(10, "MX播放器");
playersInfo.put(11, "Reex播放器");
playersInfo.put(12, "Kodi播放器");
mPlayersInfo = playersInfo;
}
return mPlayersInfo;
}
private static HashMap<Integer, Boolean> mPlayersExistInfo = null;
public static HashMap<Integer, Boolean> getPlayersExistInfo() {
if (mPlayersExistInfo == null) {
HashMap<Integer, Boolean> playersExist = new HashMap<>();
playersExist.put(0, true);
playersExist.put(1, true);
playersExist.put(2, true);
playersExist.put(10, MXPlayer.getPackageInfo() != null);
playersExist.put(11, ReexPlayer.getPackageInfo() != null);
playersExist.put(12, Kodi.getPackageInfo() != null);
mPlayersExistInfo = playersExist;
}
return mPlayersExistInfo;
}
public static Boolean getPlayerExist(int playType) {
HashMap<Integer, Boolean> playersExistInfo = getPlayersExistInfo();
if (playersExistInfo.containsKey(playType)) {
return playersExistInfo.get(playType);
} else {
return false;
}
}
public static ArrayList<Integer> getExistPlayerTypes() {
HashMap<Integer, Boolean> playersExistInfo = getPlayersExistInfo();
ArrayList<Integer> existPlayers = new ArrayList<>();
for(Integer playerType : playersExistInfo.keySet()) {
if (playersExistInfo.get(playerType)) {
existPlayers.add(playerType);
}
}
return existPlayers;
}
public static Boolean runExternalPlayer(int playerType, Activity activity, String url, String title, String subtitle, HashMap<String, String> headers) {
boolean callResult = false;
switch (playerType) {
case 10: {
callResult = MXPlayer.run(activity, url, title, subtitle, headers);
break;
}
case 11: {
callResult = ReexPlayer.run(activity, url, title, subtitle, headers);
break;
}
case 12: {
callResult = Kodi.run(activity, url, title, subtitle, headers);
break;
}
}
return callResult;
}
public static String getRenderName(int renderType) {
if (renderType == 1) {
return "SurfaceView";

Loading…
Cancel
Save