Навигация с помощью пользовательского средства визуализации Exoplayer в xamarin

#c# #xamarin #exoplayer

#c# #xamarin #exoplayer

Вопрос:

У меня есть listview на главной странице, когда я нажимаю listview, он переходит на 2-ю страницу, где у него есть интеграция Exoplayer с пользовательским средством визуализации, поэтому проблема в том, как правильно освободить проигрыватель, поскольку в настоящее время _player всегда равен нулю, воспроизводится несколько аудиозаписей, если переходить с первой страницы на 2-ю страницу несколько разраз.

Вот код пользовательского средства визуализации-

 public class VideoPlayerRenderer : ViewRenderer<VideoPlayer, SimpleExoPlayerView>, IExoPlayerEventListener
{
    private SimpleExoPlayerView _playerView;
    private SimpleExoPlayer _player;
    private DefaultTrackSelector trackSelector;
    DefaultHttpDataSourceFactory defaultHttpDataSourceFactory;
    DefaultDataSourceFactory defaultDataSourceFactory ;
    ExtractorMediaSource extractorMediaSource ;
    public VideoPlayerRenderer(Context context) : base(context)
    {

    }


    protected override void OnElementChanged(ElementChangedEventArgs<VideoPlayer> e)
    {
        base.OnElementChanged(e);

        if (_player == null)
        {
            InitializePlayer();
        }


        Play();
    }


    private void InitializePlayer()
    {

        trackSelector = new DefaultTrackSelector();

        _player = ExoPlayerFactory.NewSimpleInstance(Context,trackSelector);
        _player.PlayWhenReady = true;
        _playerView = new SimpleExoPlayerView(Context) { Player = _player };
        SetNativeControl(_playerView);
        SetBackgroundColor(Android.Graphics.Color.Green);
    }

    private void Play()
    {

            Uri sourceUri = Uri.Parse(Element.SourceUrl);
            var mediaUri = Android.Net.Uri.Parse(Element.SourceUrl);
            var userAgent = Util.GetUserAgent(Context, "App1");
             defaultHttpDataSourceFactory = new DefaultHttpDataSourceFactory(userAgent);
             defaultDataSourceFactory = new DefaultDataSourceFactory(Context, null, defaultHttpDataSourceFactory);
             extractorMediaSource = new ExtractorMediaSource(mediaUri, defaultDataSourceFactory, new DefaultExtractorsFactory(), null, null);
            _player.Prepare(extractorMediaSource);
            _player.AddListener(this);

    }
  

Ответ №1:

В вашем пользовательском средстве визуализации переопределите OnDetachedFromWindow , чтобы остановить проигрыватель:

    protected override void OnDetachedFromWindow()
    {
        base.OnDetachedFromWindow();
        _player.Stop();
        _player.Release();
    }
  

См.: onDetachedFromWindow

Обновить:

Чтобы управлять проигрывателем, вы должны создать одноэлементный элемент SimpleExoPlayer , убедитесь _player , что во всем вашем проекте есть только один:

 class ExoPlayerInstance
{

    private static SimpleExoPlayer _player;

    public static SimpleExoPlayer player
    {
        get
        {
            if (_player == null)
            {
                _player = ExoPlayerFactory.NewSimpleInstance(Application.Context, new DefaultTrackSelector());
                _player.PlayWhenReady = true;
            }
            return _player;
        }
    }
}
  

А затем в вашем пользовательском рендеринге удалите InitializePlayer часть и используйте ExoPlayerInstance :

 protected override void OnElementChanged(ElementChangedEventArgs<VideoPlayer> e)
{
    base.OnElementChanged(e);

    //remove the InitializePlayer part
    //if (_player == null)
    //    InitializePlayer();

    _player = ExoPlayerInstance.player;

    _playerView = new SimpleExoPlayerView(Context) { Player = _player };
    SetNativeControl(_playerView);

    if (_player.IsPlayingAd || _player.IsLoading)
    {
        //maybe something more need to do , stop() here is an example
        _player.Stop();
    }

    Play();
}
  

Комментарии:

1. Спасибо за ответ, я пробовал это раньше, но проблема в том, что когда я нажимаю кнопку «Назад» на 2-й странице, песня перестает воспроизводиться, но я хочу воспроизвести песню, даже если я нажимаю кнопку «Назад» или в фоновом режиме, что достаточно справедливо для аудиоплеера

2. @uncle_scrooge ХОРОШО, итак, вы хотите, чтобы песня всегда воспроизводилась, пока пользователь не приостановит ее или следующая песня не будет готова к воспроизведению? Теперь у вас проблема в том, что две песни воспроизводятся одновременно?

3. Спасибо, что уделили этому время… Я только что использовал Android.App.Application. Контекст вместо контекста выдает исключение невозможности активировать экземпляр из собственного дескриптора… вероятно, из-за непрочной абстракции.. рассмотрим подробнее ваши коды

4. @uncle_scrooge Нет проблем. Я просто высказываю вам мысль. Я думаю, что использование синглтона приведет вас к правильному решению этой проблемы.