Merge branch 'dev' into release

pull/137/head
FongMi 3 years ago
commit 8ba0e3b0f2
  1. 8
      README.md
  2. 4
      app/build.gradle
  3. 2
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/CollectActivity.java
  4. 91
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/DetailActivity.java
  5. 64
      app/src/leanback/java/com/fongmi/android/tv/ui/presenter/SearchPresenter.java
  6. 25
      app/src/leanback/res/layout/activity_detail.xml
  7. 42
      app/src/leanback/res/layout/adapter_search.xml
  8. 1
      app/src/leanback/res/layout/dialog_config.xml
  9. 18
      app/src/main/java/com/fongmi/android/tv/Constant.java
  10. 40
      app/src/main/java/com/fongmi/android/tv/api/Updater.java
  11. 1
      app/src/main/java/com/fongmi/android/tv/bean/Config.java
  12. 4
      app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java
  13. 6
      app/src/main/java/com/fongmi/android/tv/player/ExoUtil.java
  14. 2
      app/src/main/java/com/fongmi/android/tv/player/Players.java
  15. 3
      app/src/main/java/com/fongmi/android/tv/player/source/Force.java
  16. 2
      app/src/main/java/com/fongmi/android/tv/utils/Prefers.java
  17. 15
      ijkplayer/src/main/java/tv/danmaku/ijk/media/player/IjkMediaPlayer.java
  18. 2
      ijkplayer/src/main/java/tv/danmaku/ijk/media/player/ui/IjkVideoView.java
  19. 0
      other/sample/live/offline.json
  20. 0
      other/sample/live/online.json
  21. 0
      other/sample/vod/offline.json
  22. 0
      other/sample/vod/online.json

@ -8,10 +8,10 @@ https://github.com/CatVodTVOfficial/CatVodTVJarLoader
[TV-Python](https://github.com/FongMi/TV/blob/main/release/leanback-python.apk?raw=true "TV-Python")
### Config Example
[Vod-Online](other/vod-online.json)
[Vod-Offline](other/vod-offline.json)
[Live-Online](other/live-online.json)
[Live-Offline](other/live-offline.json)
[Vod-Online](other/sample/vod/online.json)
[Vod-Offline](other/sample/vod/offline.json)
[Live-Online](other/sample/live/online.json)
[Live-Offline](other/sample/live/offline.json)
### Subtitle Format
In playerContent put "sub"

@ -10,8 +10,8 @@ android {
applicationId "com.fongmi.android.tv"
minSdk 21
targetSdk 33
versionCode 46
versionName "1.4.6"
versionCode 47
versionName "1.4.7"
ndk { abiFilters "armeabi-v7a" }
}

@ -97,7 +97,7 @@ public class CollectActivity extends BaseActivity {
private void setViewModel() {
mViewModel = new ViewModelProvider(this).get(SiteViewModel.class);
mViewModel.result.observe(this, result -> {
mViewModel.search.observe(this, result -> {
mAdapter.add(Collect.create(result.getList()));
getFragment().addVideo(result.getList());
mPageAdapter.notifyDataSetChanged();

@ -45,6 +45,7 @@ import com.fongmi.android.tv.ui.presenter.EpisodePresenter;
import com.fongmi.android.tv.ui.presenter.FlagPresenter;
import com.fongmi.android.tv.ui.presenter.ParsePresenter;
import com.fongmi.android.tv.ui.presenter.PartPresenter;
import com.fongmi.android.tv.ui.presenter.SearchPresenter;
import com.fongmi.android.tv.utils.Clock;
import com.fongmi.android.tv.utils.Notify;
import com.fongmi.android.tv.utils.Prefers;
@ -60,7 +61,10 @@ import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import okhttp3.Call;
import okhttp3.Response;
@ -75,9 +79,11 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
private ArrayObjectAdapter mEpisodeAdapter;
private ArrayObjectAdapter mParseAdapter;
private ArrayObjectAdapter mPartAdapter;
private ArrayObjectAdapter mSearchAdapter;
private EpisodePresenter mEpisodePresenter;
private PartPresenter mPartPresenter;
private CustomKeyDownVod mKeyDown;
private ExecutorService mExecutor;
private SiteViewModel mViewModel;
private boolean mFullscreen;
private History mHistory;
@ -211,7 +217,10 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
mBinding.array.setAdapter(new ItemBridgeAdapter(mArrayAdapter = new ArrayObjectAdapter(new ArrayPresenter(this))));
mBinding.part.setHorizontalSpacing(ResUtil.dp2px(8));
mBinding.part.setRowHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
mBinding.part.setAdapter(new ItemBridgeAdapter(mPartAdapter = new ArrayObjectAdapter(mPartPresenter = new PartPresenter(item -> CollectActivity.start(this, item)))));
mBinding.part.setAdapter(new ItemBridgeAdapter(mPartAdapter = new ArrayObjectAdapter(mPartPresenter = new PartPresenter(this::initSearch))));
mBinding.search.setHorizontalSpacing(ResUtil.dp2px(8));
mBinding.search.setRowHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
mBinding.search.setAdapter(new ItemBridgeAdapter(mSearchAdapter = new ArrayObjectAdapter(new SearchPresenter(this::getDetail))));
mBinding.control.parse.setHorizontalSpacing(ResUtil.dp2px(8));
mBinding.control.parse.setRowHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
mBinding.control.parse.setAdapter(new ItemBridgeAdapter(mParseAdapter = new ArrayObjectAdapter(new ParsePresenter(this::setParseActivated))));
@ -253,6 +262,10 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
mViewModel.result.observe(this, result -> {
if (result.getList().isEmpty()) mBinding.progressLayout.showEmpty();
else setDetail(result.getList().get(0));
Notify.dismiss();
});
mViewModel.search.observe(this, result -> {
setSearch(result.getList());
});
}
@ -267,6 +280,17 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
mViewModel.detailContent(getKey(), getId());
}
private void getDetail(Vod item) {
getIntent().putExtra("key", item.getSite().getKey());
getIntent().putExtra("id", item.getVodId());
mBinding.scroll.scrollTo(0, 0);
Clock.get().setCallback(null);
Notify.progress(this);
mPlayers.stop();
hideProgress();
getDetail();
}
private void getPlayer(boolean replay) {
Vod.Flag.Episode item = (Vod.Flag.Episode) mEpisodeAdapter.get(getEpisodePosition());
if (mFullscreen && mPlayers.getRetry() == 0) Notify.show(ResUtil.getString(R.string.play_ready, item.getName()));
@ -307,9 +331,8 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
}
private void setText(TextView view, int resId, String text) {
if (text.isEmpty()) view.setVisibility(View.GONE);
else if (resId > 0) view.setText(ResUtil.getString(resId, text));
else view.setText(text);
view.setVisibility(text.isEmpty() ? View.GONE : View.VISIBLE);
view.setText(resId > 0 ? ResUtil.getString(resId, text) : text);
view.setTag(text);
}
@ -319,10 +342,16 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
mBinding.flag.setSelectedPosition(mFlagAdapter.indexOf(item));
mEpisodeAdapter.setItems(item.getEpisodes(), null);
notifyItemChanged(mBinding.flag, mFlagAdapter);
setArray(item.getEpisodes().size());
setEpisodeAdapter(item.getEpisodes());
seamless(item);
}
private void setEpisodeAdapter(List<Vod.Flag.Episode> items) {
mBinding.episode.setVisibility(items.isEmpty() ? View.GONE : View.VISIBLE);
mEpisodeAdapter.setItems(items, null);
setArray(items.size());
}
private void seamless(Vod.Flag flag) {
Vod.Flag.Episode episode = flag.find(mHistory.getVodRemarks());
if (episode == null || episode.isActivated()) return;
@ -342,8 +371,8 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
private void reverseEpisode() {
for (int i = 0; i < mFlagAdapter.size(); i++) Collections.reverse(((Vod.Flag) mFlagAdapter.get(i)).getEpisodes());
mEpisodeAdapter.setItems(getVodFlag().getEpisodes(), null);
setArray(mEpisodeAdapter.size());
setEpisodeAdapter(getVodFlag().getEpisodes());
mBinding.episode.setSelectedPosition(getEpisodePosition());
}
private void setParseActivated(Parse item) {
@ -367,6 +396,43 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
mArrayAdapter.setItems(items, null);
}
private void stopSearch() {
if (mExecutor != null) mExecutor.shutdownNow();
mSearchAdapter.clear();
}
private void initSearch(String keyword) {
stopSearch();
startSearch(keyword);
mBinding.part.setTag(keyword);
}
private void startSearch(String keyword) {
mExecutor = Executors.newFixedThreadPool(5);
for (Site site : ApiConfig.get().getSites()) if (site.isSearchable() && !site.getKey().equals(getKey())) mExecutor.execute(() -> search(site, keyword));
}
private void search(Site site, String keyword) {
try {
mViewModel.searchContent(site, keyword);
} catch (Throwable ignored) {
}
}
private void setSearch(List<Vod> items) {
Iterator<Vod> iterator = items.iterator();
while (iterator.hasNext()) if (mismatch(iterator.next())) iterator.remove();
mSearchAdapter.addAll(mSearchAdapter.size(), items);
mBinding.search.setVisibility(View.VISIBLE);
}
private boolean mismatch(Vod item) {
String name = mBinding.name.getText().toString();
String keyword = mBinding.part.getTag().toString();
boolean accurate = keyword.equals(name) && isVisible(mBinding.widget.error);
return accurate && !item.getVodName().equals(keyword) || !item.getVodName().contains(keyword);
}
@Override
public void onRevSort() {
mHistory.setRevSort(!mHistory.isRevSort());
@ -587,12 +653,9 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
}
private boolean hasFlag() {
if (mFlagAdapter.size() > 0) return true;
mBinding.flag.setVisibility(View.GONE);
mBinding.array.setVisibility(View.GONE);
mBinding.episode.setVisibility(View.GONE);
Notify.show(R.string.error_episode);
return false;
mBinding.flag.setVisibility(mFlagAdapter.size() > 0 ? View.VISIBLE : View.GONE);
if (mFlagAdapter.size() == 0) Notify.show(R.string.error_episode);
return mFlagAdapter.size() > 0;
}
private void checkHistory() {
@ -690,6 +753,7 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
private void onError(String msg) {
int position = mBinding.flag.getSelectedPosition();
if (position == mFlagAdapter.size() - 1) {
initSearch(mBinding.name.getText().toString());
mBinding.widget.text.setText(msg);
Clock.get().setCallback(null);
mPlayers.stop();
@ -787,6 +851,7 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
} else if (mFullscreen) {
exitFullscreen();
} else {
stopSearch();
super.onBackPressed();
}
}

@ -0,0 +1,64 @@
package com.fongmi.android.tv.ui.presenter;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.leanback.widget.Presenter;
import com.fongmi.android.tv.bean.Vod;
import com.fongmi.android.tv.databinding.AdapterSearchBinding;
import com.fongmi.android.tv.utils.ResUtil;
public class SearchPresenter extends Presenter {
private final OnClickListener mListener;
private int width;
public SearchPresenter(OnClickListener listener) {
this.mListener = listener;
setLayoutSize();
}
private void setLayoutSize() {
int space = ResUtil.dp2px(24) + ResUtil.dp2px(8 * 5);
int base = ResUtil.getScreenWidthPx() - space;
width = base / 5;
}
public interface OnClickListener {
void onItemClick(Vod item);
}
@Override
public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) {
ViewHolder holder = new ViewHolder(AdapterSearchBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
holder.binding.getRoot().getLayoutParams().width = width;
return holder;
}
@Override
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object object) {
Vod item = (Vod) object;
ViewHolder holder = (ViewHolder) viewHolder;
holder.binding.name.setText(item.getVodName());
holder.binding.site.setText(item.getSiteName());
holder.binding.remark.setText(item.getVodRemarks());
setOnClickListener(holder, view -> mListener.onItemClick(item));
}
@Override
public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
}
public static class ViewHolder extends Presenter.ViewHolder {
private final AdapterSearchBinding binding;
public ViewHolder(@NonNull AdapterSearchBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
}

@ -16,7 +16,8 @@
android:background="@color/black"
android:focusable="true"
android:focusableInTouchMode="true"
android:foreground="@drawable/selector_video">
android:foreground="@drawable/selector_video"
android:nextFocusDown="@id/flag">
<com.google.android.exoplayer2.ui.StyledPlayerView
android:id="@+id/surface"
@ -215,10 +216,12 @@
</LinearLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/video"
android:layout_marginTop="12dp">
android:layout_marginTop="12dp"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
@ -256,15 +259,12 @@
android:paddingStart="24dp"
android:paddingTop="8dp"
android:paddingEnd="24dp"
android:paddingBottom="8dp"
android:visibility="gone"
tools:visibility="visible" />
android:paddingBottom="8dp" />
<com.fongmi.android.tv.ui.custom.CustomHorizontalGridView
android:id="@+id/part"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingStart="24dp"
@ -272,6 +272,19 @@
android:paddingEnd="24dp"
android:paddingBottom="8dp" />
<androidx.leanback.widget.HorizontalGridView
android:id="@+id/search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingStart="24dp"
android:paddingTop="8dp"
android:paddingEnd="24dp"
android:paddingBottom="8dp"
android:visibility="gone" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</com.fongmi.android.tv.ui.custom.ProgressLayout>

@ -0,0 +1,42 @@
<?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="150dp"
android:layout_height="wrap_content"
android:background="@drawable/selector_item"
android:focusable="true"
android:focusableInTouchMode="true"
android:nextFocusUp="@id/part"
android:orientation="vertical">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="16sp"
tools:text="蜘蛛人" />
<TextView
android:id="@+id/site"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:singleLine="true"
android:textColor="@color/green_a_400"
android:textSize="14sp"
tools:text="泥巴"
tools:visibility="visible" />
<TextView
android:id="@+id/remark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:singleLine="true"
android:textColor="@color/yellow_500"
android:textSize="14sp"
tools:text="1080p" />
</LinearLayout>

@ -17,6 +17,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_toEndOf="@+id/code"
android:focusable="true"
android:lineSpacingExtra="4dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"

@ -0,0 +1,18 @@
package com.fongmi.android.tv;
public class Constant {
public static final String PROXY = "https://ghproxy.com/";
public static final String REPO = "https://raw.githubusercontent.com/FongMi/TV/";
public static final String RELEASE = "release";
public static final String KITKAT = "kitkat";
public static final String DEV = "dev";
public static String getReleasePath(String path) {
return PROXY + REPO + RELEASE + path;
}
public static String getBranchPath(String branch, String path) {
return PROXY + REPO + branch + path;
}
}

@ -9,6 +9,7 @@ import androidx.appcompat.app.AlertDialog;
import com.fongmi.android.tv.App;
import com.fongmi.android.tv.BuildConfig;
import com.fongmi.android.tv.Constant;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.databinding.DialogUpdateBinding;
import com.fongmi.android.tv.net.OKHttp;
@ -25,8 +26,6 @@ import java.lang.ref.WeakReference;
public class Updater implements View.OnClickListener {
private static final String PROXY = "https://ghproxy.com/";
private WeakReference<Activity> activity;
private AlertDialog dialog;
private String branch;
@ -41,8 +40,20 @@ public class Updater implements View.OnClickListener {
return Loader.INSTANCE;
}
private File getFile() {
return FileUtil.getCacheFile(branch + ".apk");
}
private String getJson() {
return Constant.getBranchPath(branch, "/release/" + BuildConfig.FLAVOR_mode + "-" + branch + ".json");
}
private String getApk() {
return Constant.getBranchPath(branch, "/release/" + BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_api + ".apk");
}
private Updater() {
this.branch = "release";
this.branch = Constant.RELEASE;
}
public Updater reset() {
@ -71,30 +82,15 @@ public class Updater implements View.OnClickListener {
connect(getJson());
}
private File getFile() {
return FileUtil.getCacheFile(branch + ".apk");
}
private String getPath() {
return "https://raw.githubusercontent.com/FongMi/TV/" + branch + "/release/";
}
private String getJson() {
return PROXY + getPath() + BuildConfig.FLAVOR_mode + "-" + branch + ".json";
}
private String getApk() {
return PROXY + getPath() + BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_api + ".apk";
}
private void connect(String target) {
try {
JSONObject object = new JSONObject(OKHttp.newCall(target).execute().body().string());
String name = object.optString("name");
String desc = object.optString("desc");
int code = object.optInt("code");
if (code > BuildConfig.VERSION_CODE || force) FileUtil.write(getFile(), OKHttp.newCall(getApk()).execute().body().bytes());
boolean show = Prefers.getUpdate() || !Prefers.getApkMd5().equals(md5 = FileUtil.getMd5(getFile()));
boolean need = code > BuildConfig.VERSION_CODE;
if (need || force) FileUtil.write(getFile(), OKHttp.newCall(getApk()).execute().body().bytes());
boolean show = need && Prefers.getUpdate() || force && !Prefers.getApkMd5().equals(md5 = FileUtil.getMd5(getFile()));
if (getFile().exists() && show) App.post(() -> checkActivity(name, desc));
} catch (Exception e) {
e.printStackTrace();
@ -124,7 +120,7 @@ public class Updater implements View.OnClickListener {
private void dismiss() {
if (dialog != null) dialog.dismiss();
this.branch = "release";
this.branch = Constant.RELEASE;
this.force = false;
this.md5 = null;
}

@ -27,7 +27,6 @@ public class Config {
public Config(String url, int type) {
this.url = url;
this.type = type;
this.time = System.currentTimeMillis();
this.id = (int) insert();
}

@ -30,11 +30,13 @@ public class SiteViewModel extends ViewModel {
public MutableLiveData<Result> result;
public MutableLiveData<Result> player;
public MutableLiveData<Result> search;
public ExecutorService executor;
public SiteViewModel() {
this.result = new MutableLiveData<>();
this.player = new MutableLiveData<>();
this.search = new MutableLiveData<>();
}
public MutableLiveData<Result> getResult() {
@ -179,7 +181,7 @@ public class SiteViewModel extends ViewModel {
private void post(Site site, Result result) {
if (result.getList().isEmpty()) return;
for (Vod vod : result.getList()) vod.setSite(site);
this.result.postValue(result);
this.search.postValue(result);
}
private void execute(MutableLiveData<Result> result, Callable<Result> callable) {

@ -7,6 +7,7 @@ import android.text.TextUtils;
import com.fongmi.android.tv.App;
import com.fongmi.android.tv.bean.Result;
import com.fongmi.android.tv.utils.FileUtil;
import com.fongmi.android.tv.utils.Prefers;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackException;
@ -50,8 +51,8 @@ public class ExoUtil {
return trackSelector;
}
public static RenderersFactory buildRenderersFactory(int decode) {
return new DefaultRenderersFactory(App.get()).setExtensionRendererMode(Math.abs(decode - 2));
public static RenderersFactory buildRenderersFactory() {
return new DefaultRenderersFactory(App.get()).setExtensionRendererMode(Math.abs(Prefers.getDecode() - 2));
}
public static CaptionStyleCompat getCaptionStyle() {
@ -74,6 +75,7 @@ public class ExoUtil {
MediaItem.Builder builder = new MediaItem.Builder().setUri(Uri.parse(url.trim()));
if (errorCode == PlaybackException.ERROR_CODE_PARSING_CONTAINER_UNSUPPORTED) builder.setMimeType(MimeTypes.APPLICATION_M3U8);
if (!TextUtils.isEmpty(sub)) builder.setSubtitleConfigurations(getSubtitles(sub));
builder.setAllowChunklessPreparation(Prefers.getDecode() == 1);
return builder.build();
}

@ -65,7 +65,7 @@ public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IM
public void setupExo(StyledPlayerView view) {
if (exoPlayer != null) releaseExo();
exoPlayer = new ExoPlayer.Builder(App.get()).setLoadControl(new DefaultLoadControl()).setRenderersFactory(ExoUtil.buildRenderersFactory(decode)).setTrackSelector(ExoUtil.buildTrackSelector()).build();
exoPlayer = new ExoPlayer.Builder(App.get()).setLoadControl(new DefaultLoadControl()).setRenderersFactory(ExoUtil.buildRenderersFactory()).setTrackSelector(ExoUtil.buildTrackSelector()).build();
exoPlayer.addAnalyticsListener(this);
exoPlayer.setPlayWhenReady(true);
exoPlayer.addListener(this);

@ -9,6 +9,7 @@ import android.os.IBinder;
import android.os.SystemClock;
import com.fongmi.android.tv.App;
import com.fongmi.android.tv.Constant;
import com.fongmi.android.tv.net.OKHttp;
import com.fongmi.android.tv.utils.FileUtil;
import com.forcetech.Port;
@ -37,7 +38,7 @@ public class Force {
private void check() throws Exception {
File file = FileUtil.getCacheFile("libmitv.so");
String url = "https://ghproxy.com/https://raw.githubusercontent.com/FongMi/TV/release/other/libmitv.so";
String url = Constant.getReleasePath("/other/libmitv.so");
if (!file.exists()) FileUtil.write(file, OKHttp.newCall(url).execute().body().bytes());
}

@ -76,7 +76,7 @@ public class Prefers {
}
public static int getDecode() {
return getInt("decode", 0);
return getInt("decode", 1);
}
public static void putDecode(int decode) {

@ -45,12 +45,16 @@ import android.view.SurfaceHolder;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import tv.danmaku.ijk.media.player.annotations.AccessedByNative;
import tv.danmaku.ijk.media.player.annotations.CalledByNative;
@ -372,7 +376,16 @@ public final class IjkMediaPlayer extends AbstractMediaPlayer {
}
}
setDataSource(uri.toString(), headers);
setDataSource(encodeSpaceChinese(uri.toString()), headers);
}
private String encodeSpaceChinese(String str) throws UnsupportedEncodingException {
Pattern p = Pattern.compile("[\u4e00-\u9fa5 ]+");
Matcher m = p.matcher(str);
StringBuffer b = new StringBuffer();
while (m.find()) m.appendReplacement(b, URLEncoder.encode(m.group(0), "UTF-8"));
m.appendTail(b);
return b.toString();
}
/**

@ -507,7 +507,7 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
mIjkPlayer.setOption(format, "http-detect-range-support", 0);
mIjkPlayer.setOption(player, "enable-accurate-seek", 0);
mIjkPlayer.setOption(player, "framedrop", 1);
mIjkPlayer.setOption(player, "max-buffer-size", 5242880);
mIjkPlayer.setOption(player, "max-buffer-size", 15 * 1024 * 1024);
mIjkPlayer.setOption(player, "mediacodec", mCurrentDecode);
mIjkPlayer.setOption(player, "mediacodec-auto-rotate", mCurrentDecode);
mIjkPlayer.setOption(player, "mediacodec-handle-resolution-change", mCurrentDecode);

Loading…
Cancel
Save