Android ExoPlayer не возобновляется после подключения сети

Я использую Exoplayer для потоковой передачи HLS в своем приложении. Его игра хорошо, но когда я отключу интернет-соединение и снова включи его, проигрыватель Exo не возобновит воспроизведение видео.

Exoplayer обрабатывает это по умолчанию или мне нужно вручную обрабатывать это?

Вот мой код …

public class PlayerActivity extends Activity implements SurfaceHolder.Callback, OnClickListener, DemoPlayer.Listener, DemoPlayer.CaptionListener, DemoPlayer.Id3MetadataListener, AudioCapabilitiesReceiver.Listener { public class PlayerActivity extends Activity implements SurfaceHolder.Callback, OnClickListener, DemoPlayer.Listener, DemoPlayer.CaptionListener, DemoPlayer.Id3MetadataListener, AudioCapabilitiesReceiver.Listener { // For use within demo app code. public static final String CONTENT_ID_EXTRA = "content_id"; public static final String CONTENT_TYPE_EXTRA = "content_type"; public static final String PROVIDER_EXTRA = "provider"; // For use when launching the demo app using adb. private static final String CONTENT_EXT_EXTRA = "type"; private static final String TAG = "PlayerActivity"; private static final int MENU_GROUP_TRACKS = 1; private static final int ID_OFFSET = 2; private static final CookieManager defaultCookieManager; static { defaultCookieManager = new CookieManager(); defaultCookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER); } private EventLogger eventLogger; private MediaController mediaController; private View debugRootView; private View shutterView; private AspectRatioFrameLayout videoFrame; private SurfaceView surfaceView; private TextView debugTextView; private TextView playerStateTextView; private SubtitleLayout subtitleLayout; private Button videoButton; private Button audioButton; private Button textButton; private Button retryButton; static TextView bitrateTextView; private static DemoPlayer player; private DebugTextViewHelper debugViewHelper; private boolean playerNeedsPrepare; private long playerPosition; private boolean enableBackgroundAudio; private Uri contentUri; private int contentType; private String contentId; private String provider; RotateAnimation rotate; ImageView rotateLoad=null; ImageView loadMid=null; FrameLayout videoLoad; private String vidLink =""; private String title =""; private TextView vodTitle; private String description =""; private TextView vodDesc; private String vodimage =""; private ImageView vodThumb; private String chimage =""; private ImageView chLogo; private String datetitle =""; private TextView vodTimeDesc, videoCurrentTime, videoTimeEnd; private Bitmap vodImgThumb, chImgLogo; private static FrameLayout guideInfo; private FrameLayout seekBar; private FrameLayout playPause; private int rewindRate = 1; private int forwardRate = 1, stopPosition ; private SeekBar sb; CountDownTimer ct; int infoFade = 0 , seekFade =0 , height, width; private boolean isPlaying = false; static long storeBitRate; private AudioCapabilitiesReceiver audioCapabilitiesReceiver; // Activity lifecycle @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.player_activity); View root = findViewById(R.id.root); shutterView = findViewById(R.id.shutter); debugRootView = findViewById(R.id.controls_root); videoFrame = (AspectRatioFrameLayout) findViewById(R.id.video_frame); surfaceView = (SurfaceView) findViewById(R.id.surface_view); surfaceView.getHolder().addCallback(this); debugTextView = (TextView) findViewById(R.id.debug_text_view); playerStateTextView = (TextView) findViewById(R.id.player_state_view); subtitleLayout = (SubtitleLayout) findViewById(R.id.subtitles); mediaController = new KeyCompatibleMediaController(this); mediaController.setAnchorView(root); // retryButton = (Button) findViewById(R.id.retry_button); // retryButton.setOnClickListener(this); videoButton = (Button) findViewById(R.id.video_controls); audioButton = (Button) findViewById(R.id.audio_controls); textButton = (Button) findViewById(R.id.text_controls); playPause = (FrameLayout)findViewById(R.id.videoPlayPause); videoLoad = (FrameLayout) findViewById(R.id.videoLoad); sb = (SeekBar)findViewById(R.id.seekBar1); // Guide Info Animator guideInfo = (FrameLayout)findViewById(R.id.guide_info); seekBar = (FrameLayout)findViewById(R.id.video_seek); playPause = (FrameLayout)findViewById(R.id.videoPlayPause); videoCurrentTime = (TextView)findViewById(R.id.video_timestart); bitrateTextView=(TextView)findViewById(R.id.bitratetext); videoTimeEnd = (TextView)findViewById(R.id.video_timeend); seekBar.setVisibility(View.GONE); playPause.setVisibility(View.GONE); root.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE || keyCode == KeyEvent.KEYCODE_MENU) { return false; } if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) { } return mediaController.dispatchKeyEvent(event); } }); CookieHandler currentHandler = CookieHandler.getDefault(); if (currentHandler != defaultCookieManager) { CookieHandler.setDefault(defaultCookieManager); } audioCapabilitiesReceiver = new AudioCapabilitiesReceiver(this, this); audioCapabilitiesReceiver.register(); } @Override public void onNewIntent(Intent intent) { releasePlayer(); playerPosition = 0; setIntent(intent); } @Override public void onResume() { super.onResume(); Intent intent = getIntent(); Bundle extras = getIntent().getExtras(); contentUri = intent.getData(); contentType = Util.TYPE_HLS; title = extras.getString("title", title); description = extras.getString("description", description); vodimage = extras.getString("vodimage", vodimage); chimage = extras.getString("chimage", chimage); datetitle = extras.getString("datetitle", datetitle); // Set Data vodTitle = (TextView)findViewById(R.id.vodTitle); vodTitle.setText(title); vodDesc = (TextView)findViewById(R.id.vodDesc); /* DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(player.getMainHandler(), null); String dfg=bandwidthMeter.getBitrateEstimate()+"";*/ vodDesc.setText(description); vodThumb = (ImageView)findViewById(R.id.vodThumb); chLogo = (ImageView)findViewById(R.id.chLogo); vodTimeDesc = (TextView)findViewById(R.id.vodTimeDesc); vodTimeDesc.setText(datetitle); rotate = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); rotate.setDuration(2000); rotate.setRepeatCount(Animation.INFINITE); rotate.setInterpolator(new LinearInterpolator()); rotateLoad= (ImageView) findViewById(R.id.lycaLoadMid_rotate); loadMid = (ImageView) findViewById(R.id.lycaLoadMid); rotateLoad.startAnimation(rotate); videoLoad = (FrameLayout) findViewById(R.id.videoLoad); //Gathering images LoadImages loadImage= new LoadImages (); loadImage.execute(vodimage,chimage); if (player == null) { // if (!maybeRequestPermission()) { preparePlayer(true); //} } else { player.setBackgrounded(false); } } @Override public void onPause() { super.onPause(); if (!enableBackgroundAudio) { releasePlayer(); } else { player.setBackgrounded(true); } shutterView.setVisibility(View.VISIBLE); } @Override public void onDestroy() { super.onDestroy(); audioCapabilitiesReceiver.unregister(); releasePlayer(); } // OnClickListener methods @Override public void onClick(View view) { if (view == retryButton) { preparePlayer(true); } } private boolean isNetworkAvailable() { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); return activeNetworkInfo != null; } // AudioCapabilitiesReceiver.Listener methods @Override public void onAudioCapabilitiesChanged(AudioCapabilities audioCapabilities) { if (player == null) { return; } boolean backgrounded = player.getBackgrounded(); boolean playWhenReady = player.getPlayWhenReady(); releasePlayer(); preparePlayer(playWhenReady); player.setBackgrounded(backgrounded); } // Permission request listener method // Internal methods private RendererBuilder getRendererBuilder() { String userAgent = Util.getUserAgent(this, "ExoPlayerDemo"); switch (contentType) { case Util.TYPE_SS: return new SmoothStreamingRendererBuilder(this, userAgent, contentUri.toString(), new SmoothStreamingTestMediaDrmCallback()); case Util.TYPE_DASH: return new DashRendererBuilder(this, userAgent, contentUri.toString(), new WidevineTestMediaDrmCallback(contentId, provider)); case Util.TYPE_HLS: return new HlsRendererBuilder(this, userAgent, contentUri.toString()); case Util.TYPE_OTHER: return new ExtractorRendererBuilder(this, userAgent, contentUri); default: throw new IllegalStateException("Unsupported type: " + contentType); } } private void preparePlayer(boolean playWhenReady) { if (player == null) { player = new DemoPlayer(getRendererBuilder()); player.addListener(this); player.setCaptionListener(this); player.setMetadataListener(this); player.seekTo(playerPosition); playerNeedsPrepare = true; mediaController.setMediaPlayer(player.getPlayerControl()); mediaController.setEnabled(true); eventLogger = new EventLogger(); eventLogger.startSession(); player.addListener(eventLogger); player.setInfoListener(eventLogger); player.setInternalErrorListener(eventLogger); //debugViewHelper = new DebugTextViewHelper(player, debugTextView); // debugViewHelper.start(); } if (playerNeedsPrepare) { player.prepare(); playerNeedsPrepare = false; updateButtonVisibilities(); } player.setSurface(surfaceView.getHolder().getSurface()); player.setPlayWhenReady(playWhenReady); guideInfo.setVisibility(View.VISIBLE); guideInfo.postDelayed(new Runnable() { public void run() { guideInfo.setVisibility(View.GONE); } }, 5000); } private void releasePlayer() { if (player != null) { debugViewHelper.stop(); debugViewHelper = null; playerPosition = player.getCurrentPosition(); player.release(); player = null; eventLogger.endSession(); eventLogger = null; } } // DemoPlayer.Listener implementation @Override public void onStateChanged(boolean playWhenReady, int playbackState) { if (playbackState == ExoPlayer.STATE_ENDED) { showControls(); } if (playbackState == ExoPlayer.STATE_BUFFERING) { if(videoLoad.getVisibility()==View.GONE){ videoLoad.setVisibility(View.VISIBLE); } } if (playbackState == ExoPlayer.STATE_READY) { videoLoad.setVisibility(View.GONE); } if (playbackState == ExoPlayer.STATE_ENDED) { videoLoad.setVisibility(View.GONE); finish(); } if(playWhenReady){ } String text = "playWhenReady=" + playWhenReady + ", playbackState="; switch(playbackState) { case ExoPlayer.STATE_BUFFERING: text += "buffering"; break; case ExoPlayer.STATE_ENDED: text += "ended"; break; case ExoPlayer.STATE_IDLE: text += "idle"; break; case ExoPlayer.STATE_PREPARING: text += "preparing"; break; case ExoPlayer.STATE_READY: text += "ready"; break; default: text += "unknown"; break; } // playerStateTextView.setText(text); updateButtonVisibilities(); } @Override public void onError(Exception e) { String errorString = null; if (e instanceof UnsupportedDrmException) { // Special case DRM failures. UnsupportedDrmException unsupportedDrmException = (UnsupportedDrmException) e; errorString = getString(Util.SDK_INT < 18 ? R.string.error_drm_not_supported : unsupportedDrmException.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME ? R.string.error_drm_unsupported_scheme : R.string.error_drm_unknown); } else if (e instanceof ExoPlaybackException && e.getCause() instanceof DecoderInitializationException) { // Special case for decoder initialization failures. DecoderInitializationException decoderInitializationException = (DecoderInitializationException) e.getCause(); if (decoderInitializationException.decoderName == null) { if (decoderInitializationException.getCause() instanceof DecoderQueryException) { errorString = getString(R.string.error_querying_decoders); } else if (decoderInitializationException.secureDecoderRequired) { errorString = getString(R.string.error_no_secure_decoder, decoderInitializationException.mimeType); } else { errorString = getString(R.string.error_no_decoder, decoderInitializationException.mimeType); } } else { errorString = getString(R.string.error_instantiating_decoder, decoderInitializationException.decoderName); } } if (errorString != null) { Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_LONG).show(); } playerNeedsPrepare = true; updateButtonVisibilities(); showControls(); } @Override public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthAspectRatio) { shutterView.setVisibility(View.GONE); videoFrame.setAspectRatio( height == 0 ? 1 : (width * pixelWidthAspectRatio) / height); } // User controls private void updateButtonVisibilities() { // retryButton.setVisibility(playerNeedsPrepare ? View.VISIBLE : View.GONE); videoButton.setVisibility(haveTracks(DemoPlayer.TYPE_VIDEO) ? View.VISIBLE : View.GONE); audioButton.setVisibility(haveTracks(DemoPlayer.TYPE_AUDIO) ? View.VISIBLE : View.GONE); textButton.setVisibility(haveTracks(DemoPlayer.TYPE_TEXT) ? View.VISIBLE : View.GONE); } private boolean haveTracks(int type) { return player != null && player.getTrackCount(type) > 0; } public void showVideoPopup(View v) { PopupMenu popup = new PopupMenu(this, v); configurePopupWithTracks(popup, null, DemoPlayer.TYPE_VIDEO); popup.show(); } public void showAudioPopup(View v) { PopupMenu popup = new PopupMenu(this, v); Menu menu = popup.getMenu(); menu.add(Menu.NONE, Menu.NONE, Menu.NONE, R.string.enable_background_audio); final MenuItem backgroundAudioItem = menu.findItem(0); backgroundAudioItem.setCheckable(true); backgroundAudioItem.setChecked(enableBackgroundAudio); OnMenuItemClickListener clickListener = new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { if (item == backgroundAudioItem) { enableBackgroundAudio = !item.isChecked(); return true; } return false; } }; configurePopupWithTracks(popup, clickListener, DemoPlayer.TYPE_AUDIO); popup.show(); } public void showTextPopup(View v) { PopupMenu popup = new PopupMenu(this, v); configurePopupWithTracks(popup, null, DemoPlayer.TYPE_TEXT); popup.show(); } public void showVerboseLogPopup(View v) { PopupMenu popup = new PopupMenu(this, v); Menu menu = popup.getMenu(); menu.add(Menu.NONE, 0, Menu.NONE, R.string.logging_normal); menu.add(Menu.NONE, 1, Menu.NONE, R.string.logging_verbose); menu.setGroupCheckable(Menu.NONE, true, true); menu.findItem((VerboseLogUtil.areAllTagsEnabled()) ? 1 : 0).setChecked(true); popup.setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { if (item.getItemId() == 0) { VerboseLogUtil.setEnableAllTags(false); } else { VerboseLogUtil.setEnableAllTags(true); } return true; } }); popup.show(); } private void configurePopupWithTracks(PopupMenu popup, final OnMenuItemClickListener customActionClickListener, final int trackType) { if (player == null) { return; } int trackCount = player.getTrackCount(trackType); if (trackCount == 0) { return; } popup.setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { return (customActionClickListener != null && customActionClickListener.onMenuItemClick(item)) || onTrackItemClick(item, trackType); } }); Menu menu = popup.getMenu(); // ID_OFFSET ensures we avoid clashing with Menu.NONE (which equals 0). menu.add(MENU_GROUP_TRACKS, DemoPlayer.TRACK_DISABLED + ID_OFFSET, Menu.NONE, R.string.off); for (int i = 0; i < trackCount; i++) { menu.add(MENU_GROUP_TRACKS, i + ID_OFFSET, Menu.NONE, buildTrackName(player.getTrackFormat(trackType, i))); } menu.setGroupCheckable(MENU_GROUP_TRACKS, true, true); menu.findItem(player.getSelectedTrack(trackType) + ID_OFFSET).setChecked(true); } private static String buildTrackName(MediaFormat format) { if (format.adaptive) { return "auto"; } String trackName; if (MimeTypes.isVideo(format.mimeType)) { trackName = joinWithSeparator(joinWithSeparator(buildResolutionString(format), buildBitrateString(format)), buildTrackIdString(format)); } else if (MimeTypes.isAudio(format.mimeType)) { trackName = joinWithSeparator(joinWithSeparator(joinWithSeparator(buildLanguageString(format), buildAudioPropertyString(format)), buildBitrateString(format)), buildTrackIdString(format)); } else { trackName = joinWithSeparator(joinWithSeparator(buildLanguageString(format), buildBitrateString(format)), buildTrackIdString(format)); } return trackName.length() == 0 ? "unknown" : trackName; } private static String buildResolutionString(MediaFormat format) { return format.width == MediaFormat.NO_VALUE || format.height == MediaFormat.NO_VALUE ? "" : format.width + "x" + format.height; } private static String buildAudioPropertyString(MediaFormat format) { return format.channelCount == MediaFormat.NO_VALUE || format.sampleRate == MediaFormat.NO_VALUE ? "" : format.channelCount + "ch, " + format.sampleRate + "Hz"; } private static String buildLanguageString(MediaFormat format) { return TextUtils.isEmpty(format.language) || "und".equals(format.language) ? "" : format.language; } private static String buildBitrateString(MediaFormat format) { String s=format.bitrate == MediaFormat.NO_VALUE ? "" : String.format(Locale.US, "%.2fMbit", format.bitrate / 1000000f); // Toast.makeText(con, s, Toast.LENGTH_LONG).show(); return s; } private static String joinWithSeparator(String first, String second) { return first.length() == 0 ? second : (second.length() == 0 ? first : first + ", " + second); } private static String buildTrackIdString(MediaFormat format) { return format.trackId == null ? "" : " (" + format.trackId + ")"; } private boolean onTrackItemClick(MenuItem item, int type) { if (player == null || item.getGroupId() != MENU_GROUP_TRACKS) { return false; } player.setSelectedTrack(type, item.getItemId() - ID_OFFSET); return true; } private void toggleControlsVisibility() { /*/////////////////////////////////// Showing defalut controllers */ if (mediaController.isShowing()) { mediaController.hide(); debugRootView.setVisibility(View.GONE); } else { showControls(); } } private void showControls() { mediaController.show(0); debugRootView.setVisibility(View.VISIBLE); } // DemoPlayer.CaptionListener implementation @Override public void onCues(List<Cue> cues) { subtitleLayout.setCues(cues); } // DemoPlayer.MetadataListener implementation @Override public void onId3Metadata(Map<String, Object> metadata) { for (Map.Entry<String, Object> entry : metadata.entrySet()) { if (TxxxMetadata.TYPE.equals(entry.getKey())) { TxxxMetadata txxxMetadata = (TxxxMetadata) entry.getValue(); Log.i(TAG, String.format("ID3 TimedMetadata %s: description=%s, value=%s", TxxxMetadata.TYPE, txxxMetadata.description, txxxMetadata.value)); } else if (PrivMetadata.TYPE.equals(entry.getKey())) { PrivMetadata privMetadata = (PrivMetadata) entry.getValue(); Log.i(TAG, String.format("ID3 TimedMetadata %s: owner=%s", PrivMetadata.TYPE, privMetadata.owner)); } else if (GeobMetadata.TYPE.equals(entry.getKey())) { GeobMetadata geobMetadata = (GeobMetadata) entry.getValue(); Log.i(TAG, String.format("ID3 TimedMetadata %s: mimeType=%s, filename=%s, description=%s", GeobMetadata.TYPE, geobMetadata.mimeType, geobMetadata.filename, geobMetadata.description)); } else { Log.i(TAG, String.format("ID3 TimedMetadata %s", entry.getKey())); } } } // SurfaceHolder.Callback implementation @Override public void surfaceCreated(SurfaceHolder holder) { if (player != null) { player.setSurface(holder.getSurface()); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // Do nothing. } @Override public void surfaceDestroyed(SurfaceHolder holder) { if (player != null) { player.blockingClearSurface(); } } private void configureSubtitleView() { CaptionStyleCompat style; float fontScale; if (Util.SDK_INT >= 19) { style = getUserCaptionStyleV19(); fontScale = getUserCaptionFontScaleV19(); } else { style = CaptionStyleCompat.DEFAULT; fontScale = 1.0f; } subtitleLayout.setStyle(style); subtitleLayout.setFractionalTextSize(SubtitleLayout.DEFAULT_TEXT_SIZE_FRACTION * fontScale); } @TargetApi(19) private float getUserCaptionFontScaleV19() { CaptioningManager captioningManager = (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE); return captioningManager.getFontScale(); } @TargetApi(19) private CaptionStyleCompat getUserCaptionStyleV19() { CaptioningManager captioningManager = (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE); return CaptionStyleCompat.createFromCaptionStyle(captioningManager.getUserStyle()); } /** * Makes a best guess to infer the type from a media {@link Uri} and an optional overriding file * extension. * * @param uri The {@link Uri} of the media. * @param fileExtension An overriding file extension. * @return The inferred type. */ private static int inferContentType(Uri uri, String fileExtension) { String lastPathSegment = !TextUtils.isEmpty(fileExtension) ? "." + fileExtension : uri.getLastPathSegment(); return Util.inferContentType(lastPathSegment); } private static final class KeyCompatibleMediaController extends MediaController { private MediaController.MediaPlayerControl playerControl; public KeyCompatibleMediaController(Context context) { super(context); } @Override public void setMediaPlayer(MediaController.MediaPlayerControl playerControl) { super.setMediaPlayer(playerControl); this.playerControl = playerControl; } @Override public boolean dispatchKeyEvent(KeyEvent event) { int keyCode = event.getKeyCode(); if (playerControl.canSeekForward() && keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) { if (event.getAction() == KeyEvent.ACTION_DOWN) { playerControl.seekTo(playerControl.getCurrentPosition() + 15000); // milliseconds BandwidthMeter bm=player.getBandwidthMeter(); Long l=bm.getBitrateEstimate(); storeBitRate=l; bitrateTextView.setText(storeBitRate+" bits/sec"); show(); } return true; } else if (playerControl.canSeekBackward() && keyCode == KeyEvent.KEYCODE_MEDIA_REWIND) { if (event.getAction() == KeyEvent.ACTION_DOWN) { playerControl.seekTo(playerControl.getCurrentPosition() - 15000); // milliseconds show(); } return true; } return super.dispatchKeyEvent(event); } } private class LoadImages extends AsyncTask<String, String, Void> { @Override protected void onPreExecute() { super.onPreExecute(); //pDialog.setVisibility(View.VISIBLE); } protected Void doInBackground(String... args) { try { vodImgThumb = BitmapFactory.decodeStream((InputStream)new URL(args[0]).getContent()); chImgLogo = BitmapFactory.decodeStream((InputStream)new URL(args[1]).getContent()); } catch (Exception e) { e.printStackTrace(); } return null; } protected void onPostExecute(Void result) { super.onPostExecute(result); vodThumb.setImageBitmap(vodImgThumb); chLogo.setImageBitmap(chImgLogo); } } } 

`

В демо ExoPlayer эта проблема обрабатывается кнопкой повтора, как показано здесь .

Прежде всего установите ErrorListener для определения некоторой ошибки, а затем просто вызовите следующую часть кода, исправьте проблему:

  if (playerNeedsPrepare) { player.prepare(); playerNeedsPrepare = false; updateButtonVisibilities(); } player.setSurface(surfaceView.getHolder().getSurface()); player.setPlayWhenReady(playWhenReady);