Возобновить Exoplayer Live Stream при потере / увеличении интернет-соединения - PullRequest
0 голосов
/ 08 июня 2018

Я работаю над Exoplayer Media Player в Android для прямой трансляции с URL-адреса RTMP Media Source.Я новичок в этом направлении, поэтому я следую официальному учебнику .Прямая трансляция работает нормально на всех устройствах Android!Мой класс для выборки живого потока:

import android.annotation.SuppressLint;
import android.databinding.DataBindingUtil;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import com.example.juni1289.exoplayertest2.databinding.ActivityMainBinding;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.ext.rtmp.RtmpDataSourceFactory;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.util.Util;
public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding binding;
    private ExoPlayer player;
    private boolean playWhenReady;
    private static final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter();
    private ComponentListener componentListener;
    private final String TAG = "MainActivity";
    private MediaSource videoSource;
    private AdaptiveTrackSelection.Factory adaptiveTrackSelectionFactory;
    private TrackSelector trackSelector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        componentListener = new ComponentListener();
        initializePlayer();
    }

    private void initializePlayer() {
        if (player == null) {
            // a factory to create an AdaptiveVideoTrackSelection
            adaptiveTrackSelectionFactory = new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);

            trackSelector = new DefaultTrackSelector(adaptiveTrackSelectionFactory);
            player = ExoPlayerFactory.newSimpleInstance(
                    new DefaultRenderersFactory(this),
                    trackSelector,
                    new DefaultLoadControl());

            binding.videoView.setPlayer(player);


            RtmpDataSourceFactory rtmpDataSourceFactory = new RtmpDataSourceFactory();

            // Produces Extractor instances for parsing the media data.
            ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
            // This is the MediaSource representing the media to be played.
            videoSource = new ExtractorMediaSource(Uri.parse(""),
                    rtmpDataSourceFactory, extractorsFactory, null, null);

            playWhenReady = true;
            player.prepare(videoSource);
            player.setPlayWhenReady(playWhenReady);
            player.addListener(componentListener);
        }
    }

    private void releasePlayer() {
        if (player != null) {
            player.removeListener(componentListener);
            playWhenReady = player.getPlayWhenReady();
            player.release();
            player = null;
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (Util.SDK_INT <= 23) {
            releasePlayer();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (Util.SDK_INT > 23) {
            releasePlayer();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        hideSystemUi();
        if ((Util.SDK_INT <= 23 || player == null)) {
            initializePlayer();
        }
    }

    @SuppressLint("InlinedApi")
    private void hideSystemUi() {
        binding.videoView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
    }

    private class ComponentListener extends Player.DefaultEventListener {
        @Override
        public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
            super.onTimelineChanged(timeline, manifest, reason);
        }

        @Override
        public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
            super.onTracksChanged(trackGroups, trackSelections);
        }

        @Override
        public void onLoadingChanged(boolean isLoading) {
            super.onLoadingChanged(isLoading);
        }

        @Override
        public void onRepeatModeChanged(int repeatMode) {
            super.onRepeatModeChanged(repeatMode);
        }

        @Override
        public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
            super.onShuffleModeEnabledChanged(shuffleModeEnabled);
        }

        @Override
        public void onPlayerError(ExoPlaybackException error) {
            super.onPlayerError(error);
        }

        @Override
        public void onPositionDiscontinuity(int reason) {
            super.onPositionDiscontinuity(reason);
        }

        @Override
        public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
            super.onPlaybackParametersChanged(playbackParameters);
        }

        @Override
        public void onSeekProcessed() {
            super.onSeekProcessed();
        }

        @Override
        public void onTimelineChanged(Timeline timeline, Object manifest) {
            super.onTimelineChanged(timeline, manifest);
        }

        @Override
        public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
            String stateString;
            switch (playbackState) {
                case ExoPlayer.STATE_IDLE:
                    stateString = "ExoPlayer.STATE_IDLE      -";
                    break;
                case ExoPlayer.STATE_BUFFERING:
                    stateString = "ExoPlayer.STATE_BUFFERING -";
                    break;
                case ExoPlayer.STATE_READY:
                    stateString = "ExoPlayer.STATE_READY     -";
                    break;
                case ExoPlayer.STATE_ENDED:
                    stateString = "ExoPlayer.STATE_ENDED     -";
                    break;
                default:
                    stateString = "UNKNOWN_STATE             -";
                    break;
            }
            Log.e(TAG, "changed state to " + stateString
                    + " playWhenReady: " + playWhenReady);
        }
    }
}

Зависимости Gradle

implementation 'com.google.android.exoplayer:exoplayer-core:2.7.3'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.7.3'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.7.3'
implementation 'com.google.android.exoplayer:extension-rtmp:2.7.3'

URL-адрес от Nginx Сервер реализован вв фоновом режиме используется программное обеспечение для потоковой передачи в реальном времени Wirecast с использованием MacBook.


Проблема, с которой я сталкиваюсь, заключается в том, что, когда я теряю соединение Wi-Fi (работает), прямая трансляцияне возобновится вообще.Точно так же и с подключением к мобильной сети 3G / 4G, когда он отключается, живой эфир не возобновляется.

Я следовал данному руководству и искал решение проблем на многих форумах!Но я не могу найти какую-либо информацию о ресурсе, чтобы исправить проблему!


Я решил для меня решение, что приемник Broadcast зарегистрирован в MainActivity, который будет проверять подключения к Интернету, как только он изменится.это заявляет, что Exoplayer будет повторно инициализирован.Но у этого есть ограничение: он работает только тогда, когда Wi-Fi или Mobile Data Connection включается или выключается!

Я хочу, чтобы Exoplayer возобновил прямой эфир, когда Wifi или Mobile Data Connection отключился, а затем он получил некотороеlife и Exoplayer возобновляют прямой эфир, чтобы снова смотреть его!

Любая помощь или руководство будут высоко оценены!Поскольку я новичок в этой разработке, в моем коде могут возникнуть любые ошибки.


Я также пытаюсь использовать следующий код:

import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Surface;

import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.ext.rtmp.RtmpDataSourceFactory;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultAllocator;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.video.VideoRendererEventListener;

public class MainActivity extends AppCompatActivity implements VideoRendererEventListener {

    private SimpleExoPlayerView exoPlayerView;
    private final String logKEY = "MainActivity";
    private SimpleExoPlayer player;
    private MediaSource videoSource;
    private final String url = "myurl";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initExoPlayer();
    }

    private void initExoPlayer() {
        try {
            BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
            AdaptiveTrackSelection.Factory videoSelectionFactory=new AdaptiveTrackSelection.Factory(bandwidthMeter);

            //TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
            TrackSelector trackSelector = new DefaultTrackSelector(videoSelectionFactory);
            /////////////////////////////////////////////////////////////////////////////////////////////////

            //////////////////////////////////////////////////////////////////////////////////////////
            //Create the player

            DefaultAllocator defaultAllocator = new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE);

            DefaultLoadControl defaultLoadControl = new DefaultLoadControl(defaultAllocator, 30,
                    30, 10, DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS,
                    DefaultLoadControl.DEFAULT_TARGET_BUFFER_BYTES, DefaultLoadControl.DEFAULT_PRIORITIZE_TIME_OVER_SIZE_THRESHOLDS);
            player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, defaultLoadControl);
            exoPlayerView.setPlayer(player);
            exoPlayerView.setUseController(false);


            RtmpDataSourceFactory rtmpDataSourceFactory = new RtmpDataSourceFactory();

            // Produces Extractor instances for parsing the media data.
            ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
            // This is the MediaSource representing the media to be played.
            videoSource = new ExtractorMediaSource(Uri.parse(url),
                    rtmpDataSourceFactory, extractorsFactory, null, null);


            // Prepare the player with the source.
            player.prepare(videoSource);
            //auto start playing
            player.setPlayWhenReady(true);
            //adding listeners
            player.addListener(new ExoPlayer.EventListener() {
                @Override
                public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {

                }

                @Override
                public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

                }

                @Override
                public void onLoadingChanged(boolean isLoading) {
                    if (isLoading) {
                        Log.e(logKEY, "loadingChanged:::true");
                    } else {
                        Log.e(logKEY, "loadingChanged:::false");
                    }
                }

                @Override
                public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

                }

                @Override
                public void onRepeatModeChanged(int repeatMode) {

                }

                @Override
                public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

                }

                @Override
                public void onPlayerError(ExoPlaybackException error) {
                    Log.e(logKEY, "Listener-onPlayerError...");
                    player.stop();
                    player.prepare(videoSource);
                    player.setPlayWhenReady(true);
                }

                @Override
                public void onPositionDiscontinuity(int reason) {

                }

                @Override
                public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

                }

                @Override
                public void onSeekProcessed() {

                }
            });
        } catch (Exception e) {
            Log.e(logKEY, "error:::" + e.toString());
            e.printStackTrace();
        }
    }

    private void initView() {
        exoPlayerView = findViewById(R.id.exoPlayerView);
    }

    @Override
    public void onVideoEnabled(DecoderCounters counters) {

    }

    @Override
    public void onVideoDecoderInitialized(String decoderName, long initializedTimestampMs, long initializationDurationMs) {

    }

    @Override
    public void onVideoInputFormatChanged(Format format) {

    }

    @Override
    public void onDroppedFrames(int count, long elapsedMs) {

    }

    @Override
    public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
        Log.e(logKEY, "onVideoSizeChanged [" + " width: " + width + " height: " + height + "]");
        Log.e(logKEY, "RES:(WxH):" + width + "X" + height + "\n           " + height + "p");
    }

    @Override
    public void onRenderedFirstFrame(Surface surface) {

    }

    @Override
    public void onVideoDisabled(DecoderCounters counters) {

    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.e(logKEY, "onStop()...");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.e(logKEY, "onStart()...");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.e(logKEY, "onResume()...");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.e(logKEY, "onPause()...");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e(logKEY, "onDestroy()...");
        player.release();
    }
}

Выше приведенотакже имеющие указанные проблемы!

...