我正在使用EXOPlayer播放HLS视频并且它工作正常。但是,如果HLS流媒体源视频有一些变化,然后视频播放停止并继续显示加载圈。 我的问题是,当视频停止时,我怎么能强制重新加载并恢复实时播放?这是我的代码
public class TvPlay extends AppCompatActivity implements HlsSampleSource.EventListener, View.OnClickListener {
public static final int RENDERER_COUNT = 2;
public static final int TYPE_AUDIO = 1;
private ExoPlayer player;
private SurfaceView surface;
private Handler mainHandler;
private TrackRenderer videoRenderer;
private LinearLayout root;
public static final int TYPE_VIDEO = 0;
private View decorView;
private int uiImmersiveOptions;
private RelativeLayout loadingPanel;
private Runnable updatePlayer, hideControls;
//Implementing current time, total time and seekbar
private TextView txt_ct, txt_td;
private SeekBar seekBar;
private PlayerControl playerControl;
public enum ControlsMode {
FULLCONTORLS
}
private ControlsMode controlsState;
private ImageButton btn_play;
private ImageButton btn_pause;
private ImageButton btn_settings;
private String url;
{
updatePlayer = new Runnable() {
@Override
public void run() {
switch (player.getPlaybackState()) {
case ExoPlayer.STATE_BUFFERING:
loadingPanel.setVisibility(View.VISIBLE);
break;
case ExoPlayer.STATE_ENDED:
finish();
break;
case ExoPlayer.STATE_IDLE:
loadingPanel.setVisibility(View.GONE);
break;
case ExoPlayer.STATE_PREPARING:
loadingPanel.setVisibility(View.VISIBLE);
break;
case ExoPlayer.STATE_READY:
loadingPanel.setVisibility(View.GONE);
break;
default:
break;
}
String totDur = String.format("%02d.%02d.%02d",
TimeUnit.MILLISECONDS.toHours(player.getDuration()),
TimeUnit.MILLISECONDS.toMinutes(player.getDuration()) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(player.getDuration())), // The change is in this line
TimeUnit.MILLISECONDS.toSeconds(player.getDuration()) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(player.getDuration())));
String curDur = String.format("%02d.%02d.%02d",
TimeUnit.MILLISECONDS.toHours(player.getCurrentPosition()),
TimeUnit.MILLISECONDS.toMinutes(player.getCurrentPosition()) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(player.getCurrentPosition())), // The change is in this line
TimeUnit.MILLISECONDS.toSeconds(player.getCurrentPosition()) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(player.getCurrentPosition())));
txt_ct.setText(curDur);
txt_td.setText(totDur);
seekBar.setMax((int) player.getDuration());
seekBar.setProgress((int) player.getCurrentPosition());
mainHandler.postDelayed(updatePlayer, 200);
}
};
}
{
hideControls = new Runnable() {
@Override
public void run() {
hideAllControls();
}
};
}
private void hideAllControls() {
if (controlsState == ControlsMode.FULLCONTORLS) {
if (root.getVisibility() == View.VISIBLE) {
root.setVisibility(View.GONE);
}
}
decorView.setSystemUiVisibility(uiImmersiveOptions);
}
private void showControls() {
if (controlsState == ControlsMode.FULLCONTORLS) {
if (root.getVisibility() == View.GONE) {
root.setVisibility(View.VISIBLE);
}
}
mainHandler.removeCallbacks(hideControls);
mainHandler.postDelayed(hideControls, 5000);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
showControls();
break;
}
return super.onTouchEvent(event);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tvplay);
url=getIntent().getStringExtra("url");
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
uiImmersiveOptions = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
);
decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(uiImmersiveOptions);
loadingPanel = (RelativeLayout) findViewById(R.id.loadingVPanel);
txt_ct = (TextView) findViewById(R.id.txt_currentTime);
txt_td = (TextView) findViewById(R.id.txt_totalDuration);
seekBar = (SeekBar) findViewById(R.id.seekbar);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
player.seekTo(seekBar.getProgress());
}
});
btn_play = (ImageButton) findViewById(R.id.btn_play);
btn_pause = (ImageButton) findViewById(R.id.btn_pause);
btn_settings = (ImageButton) findViewById(R.id.btn_settings);
btn_play.setOnClickListener(this);
btn_pause.setOnClickListener(this);
btn_settings.setOnClickListener(this);
root = (LinearLayout) findViewById(R.id.root);
root.setVisibility(View.VISIBLE);
surface = (SurfaceView) findViewById(R.id.surface_view);
mainHandler = new Handler();
execute();
}
@Override
public void onClick(View v) {
int i1 = v.getId();
if (i1 == R.id.btn_pause) {
if (playerControl.isPlaying()) {
playerControl.pause();
btn_pause.setVisibility(View.GONE);
btn_play.setVisibility(View.VISIBLE);
}
}
if (i1 == R.id.btn_play) {
if (!playerControl.isPlaying()) {
playerControl.start();
btn_pause.setVisibility(View.VISIBLE);
btn_play.setVisibility(View.GONE);
}
}
if (i1 == R.id.btn_settings) {
PopupMenu popup = new PopupMenu(TvPlay.this, v);
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
player.setSelectedTrack(0, (item.getItemId() - 1));
return false;
}
});
Menu menu = popup.getMenu();
menu.add(Menu.NONE, 0, 0, "Video Quality");
for (int i = 0; i < player.getTrackCount(0); i++) {
MediaFormat format = player.getTrackFormat(0, i);
if (MimeTypes.isVideo(format.mimeType)) {
if (format.adaptive) {
menu.add(1, (i + 1), (i + 1), "Auto");
} else {
menu.add(1, (i + 1), (i + 1), format.bitrate/1000 + " kbps");
}
}
}
menu.setGroupCheckable(1, true, true);
menu.findItem((player.getSelectedTrack(0) + 1)).setChecked(true);
popup.show();
}
}
private void execute() {
player = ExoPlayer.Factory.newInstance(RENDERER_COUNT);
playerControl = new PlayerControl(player);
if (player != null) {
HpLib_RendererBuilder hpLibRendererBuilder = getHpLibRendererBuilder();
hpLibRendererBuilder.buildRenderers(this);
loadingPanel.setVisibility(View.VISIBLE);
mainHandler.postDelayed(updatePlayer, 200);
mainHandler.postDelayed(hideControls, 3000);
controlsState = ControlsMode.FULLCONTORLS;
}
}
private HpLib_RendererBuilder getHpLibRendererBuilder() {
String userAgent = Util.getUserAgent(this, "AndroidLiveTV");
if(url.endsWith(".m3u8")){
return new HpLib_HlsHpLibRendererBuilder(this, userAgent, url);
}else{
return new HpLib_ExtractorHpLibRendererBuilder(this, userAgent, Uri.parse(url));
}
/*
switch (video_type[currentTrackIndex]) {
case "hls":
return new HpLib_HlsHpLibRendererBuilder(this, userAgent, video_url[currentTrackIndex]);
case "others":
return new HpLib_ExtractorHpLibRendererBuilder(this, userAgent, Uri.parse(video_url[currentTrackIndex]));
default:
throw new IllegalStateException("Unsupported type: " + video_url[currentTrackIndex]);
}
*/
}
Handler getMainHandler() {
return mainHandler;
}
void onRenderersError(Exception e) {
}
void onRenderers(TrackRenderer[] renderers, BandwidthMeter bandwidthMeter) {
for (int i = 0; i < renderers.length; i++) {
if (renderers[i] == null) {
renderers[i] = new DummyTrackRenderer();
}
}
// Complete preparation.
this.videoRenderer = renderers[TYPE_VIDEO];
pushSurface(false);
player.prepare(renderers);
player.setPlayWhenReady(true);
}
private void pushSurface(boolean blockForSurfacePush) {
if (videoRenderer == null) {
return;
}
if (blockForSurfacePush) {
player.blockingSendMessage(
videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface.getHolder().getSurface());
} else {
player.sendMessage(
videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface.getHolder().getSurface());
}
}
private void killPlayer() {
if (player != null) {
player.release();
}
}
@Override
public void onBackPressed() {
super.onBackPressed();
killPlayer();
}
@Override
public void onLoadStarted(int sourceId, long length, int type, int trigger, Format format, long mediaStartTimeMs, long mediaEndTimeMs) {
}
@Override
public void onLoadCompleted(int sourceId, long bytesLoaded, int type, int trigger, Format format, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs) {
}
@Override
public void onLoadCanceled(int sourceId, long bytesLoaded) {
}
@Override
public void onLoadError(int sourceId, IOException e) {
}
@Override
public void onUpstreamDiscarded(int sourceId, long mediaStartTimeMs, long mediaEndTimeMs) {
}
@Override
public void onDownstreamFormatChanged(int sourceId, Format format, int trigger, long mediaTimeMs) {
}