Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

when the stream is interrupted, the client wont auto reconnect #6

Open
orangpelupa opened this issue Nov 10, 2021 · 5 comments
Open

Comments

@orangpelupa
Copy link

reproduction:

  1. start an RTSP stream, play the stream on the android app
  2. stop the stream, the stream on android app will be frozen on the last frame.
  3. start the stream, the stream on anroid app did not auto reconnect.

need to close the view (pressing back) and opening the view again on the app to reconnect the stream.

@warren-bank
Copy link
Owner

warren-bank commented Nov 12, 2021

Hi. I just updated ExoPlayer to r2.16.0 ..which is the most recent stable release. RTSP is now officially supported.. so the experimental dependency is no-longer needed.

Regarding your issue..

  • the logic to handle how many times to attempt a retry.. how much time to wait between each attempt.. etc, would normally be handled by an implementation of the LoadErrorHandlingPolicy interface.. which would typically be based on the DefaultLoadErrorHandlingPolicy class
  • implementations of MediaSourceFactory have a setLoadErrorHandlingPolicy(LoadErrorHandlingPolicy loadErrorHandlingPolicy) method to accept such a policy
  • RtspMediaSource.Factory does not yet support this feature.. and the method to accept this policy doesn't actually do anything
    • when ExoPlayer does add support to RtspMediaSource for using a LoadErrorHandlingPolicy.. I'll be sure to add one

@warren-bank
Copy link
Owner

what I just said about LoadErrorHandlingPolicy applies to adding the ability for each instance of ExoPlayer to automatically resume playback..

however, (thinking out loud atm).. there's no reason I couldn't add some logic that could be manually triggered by the user. For example:

  • in low-res list or grid layout, a long-press currently toggles between pause/resume..
    • when the video is to resume, I could detect playback state and retry (if needed)
  • in high-res full-screen layout, the visible controls overlay includes a button to toggle between pause/resume..
    • the same behavior could be added

@warren-bank
Copy link
Owner

warren-bank commented Nov 13, 2021

note to self..

attempted the following sledge-hammer approach.. by retrying any instance of ExoPlayer after a 5-second delay anytime there is any error; it still didn't resume video playback after network connectivity is lost and then subsequently re-established (ie: while in airplane mode, toggle wifi off and then back on):

package com.github.warren_bank.rtsp_ipcam_viewer.common.exoplayer2;

import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player;

import android.os.Handler;
import android.os.Looper;

public final class PlayerErrorListener implements Player.Listener {
  private static int RETRY_DELAY_MS = 5000;

  private ExoPlayer player;
  private boolean   pending;
  private Handler   handler;
  private Runnable  runnable;

  public PlayerErrorListener(ExoPlayer player) {
    this.player   = player;
    this.pending  = false;
    this.handler  = new Handler(Looper.getMainLooper());
    this.runnable = new Runnable() {
      @Override
      public void run() {
        pending = false;

        try {
          player.setPlayWhenReady(false);
          player.seekToDefaultPosition(0);
          player.retry();
          player.setPlayWhenReady(true);
        }
        catch(Exception e) {}
      }
    };
  }

  @Override
  public void onPlayerError(PlaybackException error) {
    if (!pending && player.getPlayWhenReady() && (player.getMediaItemCount() > 0)) {
      pending = true;
      handler.postDelayed(runnable, RETRY_DELAY_MS);
    }
  }
}

public final class ExoPlayerUtils {
  //...
  public static ExoPlayer initializeExoPlayer(Context context) {
    context = context.getApplicationContext();

    if (USER_AGENT == null)
      setUserAgent(context);

    ExoPlayer player = new ExoPlayer.Builder(
      context,
      getRenderersFactory(context),
      getMediaSourceFactory(context),
      getTrackSelector(context),
      getLoadControl(),
      getBandwidthMeter(context),
      getAnalyticsCollector()
    ).build();

    player.addListener(
      new PlayerErrorListener(player)
    );

    return player;
  }
}

@warren-bank
Copy link
Owner

warren-bank commented Nov 13, 2021

Based on the above observations.. we're definitely going to need to wait until the RTSP library is made more robust.. with code to support fixing broken streams. My understanding of RTSP is that the protocol has a ton of handshaking.. it's not stateless.. so it's not as simple as resending a failed request.

@warren-bank
Copy link
Owner

cross-reference to related exoplayer issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants