Update timeout system

pull/123/head
FongMi 3 years ago
parent 06fbd4a4f5
commit a2ccd701b7
  1. 12
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/DetailActivity.java
  2. 18
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/LiveActivity.java
  3. 31
      app/src/main/java/com/fongmi/android/tv/Constant.java
  4. 2
      app/src/main/java/com/fongmi/android/tv/bean/Channel.java
  5. 27
      app/src/main/java/com/fongmi/android/tv/model/LiveViewModel.java
  6. 11
      app/src/main/java/com/fongmi/android/tv/player/ParseTask.java
  7. 30
      app/src/main/java/com/fongmi/android/tv/player/Players.java
  8. 15
      app/src/main/java/com/fongmi/android/tv/ui/custom/CustomWebView.java

@ -101,7 +101,6 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
private int mCurrent;
private Runnable mR1;
private Runnable mR2;
private Runnable mR3;
public static void start(Activity activity, String id, String name) {
start(activity, ApiConfig.get().getHome().getKey(), id, name);
@ -189,7 +188,6 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
mFrameParams = mBinding.video.getLayoutParams();
mBinding.progressLayout.showProgress();
mPlayers = new Players().init();
mR3 = ErrorEvent::timeout;
mR1 = this::hideControl;
mR2 = this::setTraffic;
setRecyclerView();
@ -333,7 +331,6 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
if (result != null) {
mBinding.control.parseLayout.setVisibility(mParseAdapter.size() > 0 && useParse ? View.VISIBLE : View.GONE);
mPlayers.start(result, useParse);
setR3Callback();
} else {
ErrorEvent.url();
}
@ -662,11 +659,6 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
App.post(mR1, Constant.INTERVAL_HIDE);
}
private void setR3Callback() {
App.removeCallbacks(mR3);
App.post(mR3, Constant.TIMEOUT_VOD);
}
private void getPart(String source) {
OkHttp.newCall("http://api.pullword.com/get.php?source=" + URLEncoder.encode(source.trim()) + "&param1=0&param2=0&json=1").enqueue(new Callback() {
@Override
@ -775,7 +767,6 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
mPlayers.reset();
setDefaultTrack();
setTrackVisible(true);
App.removeCallbacks(mR3);
mBinding.widget.size.setText(mPlayers.getSizeText());
break;
case Player.STATE_ENDED:
@ -811,7 +802,6 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
private void onError(ErrorEvent event) {
Clock.get().setCallback(null);
showError(event.getMsg());
App.removeCallbacks(mR3);
hideProgress();
mPlayers.reset();
checkError(event);
@ -1045,6 +1035,6 @@ public class DetailActivity extends BaseActivity implements CustomKeyDownVod.Lis
protected void onDestroy() {
super.onDestroy();
mPlayers.release();
App.removeCallbacks(mR1, mR2, mR3);
App.removeCallbacks(mR1, mR2);
}
}

@ -86,7 +86,6 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
private Runnable mR2;
private Runnable mR3;
private Runnable mR4;
private Runnable mR5;
private int count;
public static void start(Activity activity) {
@ -133,7 +132,6 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
mR2 = this::hideControl;
mR3 = this::setChannelActivated;
mR4 = this::setTraffic;
mR5 = this::onError;
mPlayers = new Players().init();
mKeyDown = CustomKeyDownLive.create(this);
mFormatDate = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
@ -209,10 +207,8 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
private void setViewModel() {
mViewModel = new ViewModelProvider(this).get(LiveViewModel.class);
mViewModel.result.observe(this, result -> {
if (result instanceof Live) setGroup((Live) result);
else if (result instanceof Channel) mPlayers.start((Channel) result);
});
mViewModel.channel.observe(this, result -> mPlayers.start(result));
mViewModel.live.observe(this, this::setGroup);
}
private void getLive() {
@ -397,11 +393,6 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
App.post(mR2, Constant.INTERVAL_HIDE);
}
private void setR5Callback() {
App.removeCallbacks(mR5);
App.post(mR5, Constant.TIMEOUT_LIVE);
}
private void resetPass() {
this.count = 0;
}
@ -487,7 +478,6 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
private void getUrl() {
mViewModel.getUrl(mChannel);
setR5Callback();
showProgress();
}
@ -674,7 +664,6 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
hideProgress();
mPlayers.reset();
setTrackVisible(true);
App.removeCallbacks(mR5);
break;
case Player.STATE_ENDED:
onKeyDown();
@ -694,7 +683,6 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
}
private void onError() {
App.removeCallbacks(mR5);
mPlayers.reset();
checkNext();
}
@ -742,6 +730,6 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick
Force.get().stop();
ZLive.get().stop();
TVBus.get().quit();
App.removeCallbacks(mR1, mR2, mR3, mR4, mR5);
App.removeCallbacks(mR1, mR2, mR3, mR4);
}
}

@ -1,29 +1,32 @@
package com.fongmi.android.tv;
public class Constant {
//快進時間單位 10 秒
//快進時間單位
public static final int INTERVAL_SEEK = 10 * 1000;
//控件隱藏時間 5 秒
//控件隱藏時間
public static final int INTERVAL_HIDE = 5 * 1000;
//網路偵測間隔 0.5 秒
//網路偵測間隔
public static final int INTERVAL_TRAFFIC = 500;
//點播超時時間 15 秒
public static final int TIMEOUT_VOD = 15 * 1000;
//直播超時時間 10 秒
//點播爬蟲時間
public static final int TIMEOUT_VOD = 30 * 1000;
//直播解析時間
public static final int TIMEOUT_LIVE = 10 * 1000;
//解析超時時間 30 秒
//播放超時時間
public static final int TIMEOUT_PLAY = 15 * 1000;
//解析預設時間
public static final int TIMEOUT_PARSE_DEF = 5 * 1000;
//解析超時時間
public static final int TIMEOUT_PARSE_WEB = 15 * 1000;
//解析超時時間 10 秒
//解析超時時間
public static final int TIMEOUT_PARSE_JSON = 10 * 1000;
//解析超時時間 15 秒
//解析超時時間
public static final int TIMEOUT_PARSE_JSON_EXT = 15 * 1000;
//解析超時時間 15 秒
//解析超時時間
public static final int TIMEOUT_PARSE_JSON_MIX = 15 * 1000;
//網路超時時間 30 秒
//網路超時時間
public static final int TIMEOUT_HTTP = 30 * 1000;
//代理超時時間 5 秒
//代理超時時間
public static final int TIMEOUT_GITHUB = 5 * 1000;
//搜尋線程數量 5 個
//搜尋線程數量
public static final int THREAD_POOL = 5;
}

@ -120,7 +120,7 @@ public class Channel {
}
public String getUrl() {
return url;
return TextUtils.isEmpty(url) ? "" : url;
}
public void setUrl(String url) {

@ -18,22 +18,27 @@ import java.util.concurrent.TimeUnit;
public class LiveViewModel extends ViewModel {
public MutableLiveData<Object> result;
private static final int LIVE = 1;
private static final int CHANNEL = 2;
public MutableLiveData<Channel> channel;
public MutableLiveData<Live> live;
public ExecutorService executor;
public LiveViewModel() {
this.result = new MutableLiveData<>();
this.channel = new MutableLiveData<>();
this.live = new MutableLiveData<>();
}
public void getLive(Live home) {
execute(() -> {
LiveParser.start(home);
return home;
public void getLive(Live item) {
execute(LIVE, () -> {
LiveParser.start(item);
return item;
});
}
public void getUrl(Channel item) {
execute(() -> {
execute(CHANNEL, () -> {
TVBus.get().stop();
String url = item.getCurrent().split("\\$")[0];
if (item.isForce()) item.setUrl(Force.get().fetch(url));
@ -44,14 +49,18 @@ public class LiveViewModel extends ViewModel {
});
}
private void execute(Callable<?> callable) {
private void execute(int type, Callable<?> callable) {
if (executor != null) executor.shutdownNow();
executor = Executors.newFixedThreadPool(2);
executor.execute(() -> {
try {
if (!Thread.interrupted()) result.postValue(executor.submit(callable).get(Constant.TIMEOUT_LIVE, TimeUnit.MILLISECONDS));
if (!Thread.interrupted() && type == LIVE) live.postValue((Live) executor.submit(callable).get(Constant.TIMEOUT_HTTP, TimeUnit.MILLISECONDS));
if (!Thread.interrupted() && type == CHANNEL) channel.postValue((Channel) executor.submit(callable).get(Constant.TIMEOUT_LIVE, TimeUnit.MILLISECONDS));
} catch (Throwable e) {
e.printStackTrace();
if (e instanceof InterruptedException) return;
if (!Thread.interrupted() && type == LIVE) live.postValue(new Live());
if (!Thread.interrupted() && type == CHANNEL) channel.postValue(new Channel());
}
});
}

@ -58,6 +58,7 @@ public class ParseTask {
try {
executor.submit(getTask(result)).get(getTimeout(), TimeUnit.MILLISECONDS);
} catch (Throwable e) {
;
onParseError();
}
});
@ -75,8 +76,6 @@ public class ParseTask {
private int getTimeout() {
switch (parse.getType()) {
case 0: //嗅探
return Constant.TIMEOUT_PARSE_WEB;
case 1: //Json
return Constant.TIMEOUT_PARSE_JSON;
case 2: //Json 擴展
@ -84,7 +83,7 @@ public class ParseTask {
case 3: //聚合
return Constant.TIMEOUT_PARSE_JSON_MIX;
default:
return Constant.TIMEOUT_VOD;
return Constant.TIMEOUT_PARSE_DEF;
}
}
@ -152,18 +151,20 @@ public class ParseTask {
private void onParseSuccess(Map<String, String> headers, String url, String from) {
App.post(() -> {
if (callback != null) callback.onParseSuccess(headers, url, from);
stop();
});
}
private void onParseError() {
App.post(() -> {
if (callback != null) callback.onParseError();
stop();
});
}
public void cancel() {
public void stop() {
if (executor != null) executor.shutdownNow();
if (webView != null) webView.stop();
if (webView != null) webView.stop(false);
executor = null;
callback = null;
webView = null;

@ -5,6 +5,7 @@ import android.net.Uri;
import androidx.annotation.NonNull;
import com.fongmi.android.tv.App;
import com.fongmi.android.tv.Constant;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.api.ApiConfig;
import com.fongmi.android.tv.bean.Channel;
@ -41,6 +42,7 @@ public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IM
private Formatter formatter;
private ParseTask parseTask;
private ExoPlayer exoPlayer;
private Runnable timeout;
private int errorCode;
private int retry;
private int decode;
@ -57,6 +59,7 @@ public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IM
public Players init() {
player = Prefers.getPlayer();
decode = Prefers.getDecode();
timeout = ErrorEvent::timeout;
builder = new StringBuilder();
formatter = new Formatter(builder, Locale.getDefault());
return this;
@ -264,7 +267,11 @@ public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IM
}
public void start(Channel channel) {
setMediaSource(channel.getHeaders(), channel.getUrl());
if (channel.getUrl().isEmpty()) {
ErrorEvent.url();
} else {
setMediaSource(channel.getHeaders(), channel.getUrl());
}
}
public void start(Result result, boolean useParse) {
@ -319,11 +326,15 @@ public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IM
}
private void stopParse() {
if (parseTask != null) parseTask.cancel();
if (parseTask != null) parseTask.stop();
}
private boolean isAds(String url) {
return ApiConfig.get().getAds().contains(Uri.parse(url).getHost());
try {
return ApiConfig.get().getAds().contains(Uri.parse(url).getHost());
} catch (Exception e) {
return false;
}
}
private void setMediaSource(Result result) {
@ -331,7 +342,7 @@ public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IM
if (isIjk()) ijkPlayer.setMediaSource(result.getPlayUrl() + result.getUrl(), result.getHeaders());
if (isExo()) exoPlayer.setMediaSource(ExoUtil.getSource(result, errorCode));
if (isExo()) exoPlayer.prepare();
PlayerEvent.state(0);
setTimeoutCheck();
}
private void setMediaSource(Map<String, String> headers, String url) {
@ -339,7 +350,13 @@ public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IM
if (isIjk()) ijkPlayer.setMediaSource(url, headers);
if (isExo()) exoPlayer.setMediaSource(ExoUtil.getSource(headers, url, errorCode));
if (isExo()) exoPlayer.prepare();
setTimeoutCheck();
}
private void setTimeoutCheck() {
PlayerEvent.state(0);
App.removeCallbacks(timeout);
App.post(timeout, Constant.TIMEOUT_PLAY);
}
private void setTrack(Track item) {
@ -377,11 +394,13 @@ public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IM
@Override
public void onPlayerError(@NonNull PlaybackException error) {
this.errorCode = error.errorCode;
App.removeCallbacks(timeout);
ErrorEvent.format();
}
@Override
public void onPlaybackStateChanged(int state) {
if (state == Player.STATE_READY) App.removeCallbacks(timeout);
PlayerEvent.state(state);
}
@ -395,6 +414,7 @@ public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IM
case IMediaPlayer.MEDIA_INFO_VIDEO_SEEK_RENDERING_START:
case IMediaPlayer.MEDIA_INFO_AUDIO_SEEK_RENDERING_START:
PlayerEvent.state(Player.STATE_READY);
App.removeCallbacks(timeout);
return true;
default:
return true;
@ -403,6 +423,7 @@ public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IM
@Override
public boolean onError(IMediaPlayer mp, int what, int extra) {
App.removeCallbacks(timeout);
ErrorEvent.format();
return true;
}
@ -410,6 +431,7 @@ public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IM
@Override
public void onPrepared(IMediaPlayer mp) {
PlayerEvent.state(Player.STATE_READY);
App.removeCallbacks(timeout);
}
@Override

@ -16,6 +16,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.fongmi.android.tv.App;
import com.fongmi.android.tv.Constant;
import com.fongmi.android.tv.api.ApiConfig;
import com.fongmi.android.tv.bean.Site;
import com.fongmi.android.tv.player.ParseTask;
@ -33,6 +34,7 @@ public class CustomWebView extends WebView {
private ParseTask.Callback callback;
private WebResourceResponse empty;
private List<String> keys;
private Runnable mTimer;
private String key;
public static CustomWebView create(@NonNull Context context) {
@ -68,6 +70,7 @@ public class CustomWebView extends WebView {
}
public CustomWebView start(String key, String url, Map<String, String> headers, ParseTask.Callback callback) {
App.post(mTimer = () -> stop(true), Constant.TIMEOUT_PARSE_WEB);
this.callback = callback;
setUserAgent(headers);
loadUrl(url, headers);
@ -116,15 +119,21 @@ public class CustomWebView extends WebView {
App.post(() -> onSuccess(news, url));
}
public void stop() {
public void stop(boolean error) {
stopLoading();
loadUrl("about:blank");
callback = null;
App.removeCallbacks(mTimer);
if (error) App.post(this::onError);
}
private void onSuccess(Map<String, String> news, String url) {
if (callback != null) callback.onParseSuccess(news, url, "");
callback = null;
stop();
stop(false);
}
private void onError() {
if (callback != null) callback.onParseError();
callback = null;
}
}

Loading…
Cancel
Save