在Exoplayer中,如何自动重新加载和恢复播放?

时间:2017-04-12 20:03:19

标签: android video exoplayer

我正在使用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) {

}

0 个答案:

没有答案