Музыкальный / видеоплеер - одно из первых важных приложений, которые мы загружаем на свой телефон, когда покупаем новое. Кроме того, музыкальное / видео-приложение прошло долгий путь, и теперь большая часть контента передается через изменяющуюся мобильную сеть вместе с новым типом контента, которым делятся люди, таким как 3D-видео и контент.
В этой статье мы узнаем, как преодолеть все эти проблемы и поддержать новый тип контента в приложении для Android с помощью библиотеки ExoPlayer.

Статья утомляет меня, покажи мне код

Если вы хотите сразу перейти к коду, загляните в следующий репозиторий GitHub с соответствующей документацией по коду.



Обзор ExoPlayer

ExoPlayer - это библиотека с открытым исходным кодом, отдельная от Android Framework, но построенная поверх Android MediaCodec API и поддерживающая важные функции, такие как Динамическая адаптивная потоковая передача через HTTP (DASH), Плавная потоковая передача, Общее шифрование, которое не поддерживается Android. встроенный медиа-API.

Новые стандарты и требования - DASH, плавная потоковая передача и общее шифрование (необязательно)

В прошлом большинство видео и аудио использовали протоколы потоковой передачи, такие как RTP (протокол реального времени) или RTSP (протокол потоковой передачи в реальном времени), что означает, что он полагается на постоянное соединение между вашим устройством и сервером, отправляющим видео / аудио. Проблема с этим подходом заключается в том, что, поскольку он имеет отслеживание состояния, он использует большую пропускную способность и не имеет возможности изменять источник во время выполнения, и поэтому менее подходит для текущих потребностей мобильных вычислений.

Новые технологии, такие как DASH от MPEG и Smooth Streaming от Microsoft, решают эту проблему, основывая свою технологию на HTTP-соединении без сохранения состояния и имея адаптивную потоковую передачу битрейта. Основным преимуществом этих технологий является то, что они гораздо более гибкие, например, источник видео можно изменять во время выполнения, видео можно транслировать из любого сегмента видео.

Ознакомьтесь со следующей серией статей от HowStuffWorks, в которой подробно описаны RTS и DASH.



Давайте начнем

Добавить зависимости - Build.gradle (Модуль: приложение)

dependencies {
    //Other dependenices
    
    //Exoplayer
    implementation "com.google.android.exoplayer:exoplayer:$exoPlayerVersion"

    //Exoplayer IMA(Interactive Media Ads)
    implementation ("com.google.android.exoplayer:extension-ima:$exoPlayerVersion"){
        exclude module: 'support-v4'
    }
}

Добавление макета

<com.google.android.exoplayer2.ui.PlayerView
   android:id="@+id/player_view"
   android:layout_width="match_parent"
   android:layout_height="match_parent"/>

Воспроизведение основного видео

Для воспроизведения основного видео нам нужно выполнить следующие простые шаги: -

Настройка просмотра проигрывателя

Получите ссылку на PlayerView, определенный в макете.

@Override
protected void onCreate(Bundle savedInstanceState) {

   playerView = findViewById(R.id.player_view);
}

Инициализировать проигрыватель

  1. Следующим шагом будет инициализация нашего экземпляра видеоплеера. Для этого требуется: -
    * Renderer - Он занимается настройкой соединения (HTTP / локальное) с источником, воспроизведением видео, даже прослушивателем и обработчиком.
    * Track Селектор - Как следует из названия, он занимается выбором треков и управлением ими, которые будут использоваться средством рендеринга.
    * Контроль загрузки - Он управляет буферизацией мультимедиа. .
  2. Затем нам нужно настроить параметры для проигрывателя.
    * playWhenReady - логический параметр, который Устанавливает, должно ли воспроизведение продолжаться, когда PlaybackState имеет значение STATE_READY. Также, если проигрыватель уже находится в состоянии готовности, этот метод можно использовать для приостановки и возобновления воспроизведения. Инициализируйте это с помощью True.
    * currentWindowIndex - Это целочисленное значение, которое возвращает индекс текущего окна (представьте его как буферную корзину), воспроизводимого в данный момент.
    * playsPosition - это кадр, в котором в данный момент находится воспроизведение.
  3. Подключаю все. Наконец, мы соединим все вместе, чтобы наша функция initializePlayer стала такой:
private void initializePlayer() {
     player = ExoPlayerFactory.newSimpleInstance(
         new DefaultRenderersFactory(this),
         new DefaultTrackSelector(), new DefaultLoadControl());

     playerView.setPlayer(player);

     player.setPlayWhenReady(playWhenReady);
     player.seekTo(currentWindow, playbackPosition);
}

Создать источник мультимедиа

Следующим шагом является создание медиа-источника, который является источником нашего медиа-файла для созданного выше плеера. Exoplayer поставляется со многими фабриками MediaSource по умолчанию, как показано в коде ниже: -

Подключи все и играй

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

В полноэкранный режим

    @SuppressLint("InlinedApi")
    private fun hideSystemUi() {
        playerView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LOW_PROFILE
                or View.SYSTEM_UI_FLAG_FULLSCREEN
                or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)
    }

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

    var currUri = null 
    var currUriList = null
//Play single video
    fun play(uri: Uri?){
        if(uri == null) return
        currUri = uri
        initPlayer()
        preparePlayer(uri!!)
        hideSystemUi()
    }

    //Overloaded function to play the whole playlist
    fun play(uriList : Array<Uri>?){
        if(uriList == null) return
        currUriList = uriList
        initPlayer()
        preparePlayer(uriList!!)
        hideSystemUi()
    }

Обработка жизненного цикла игрока

Наконец, мы будем обрабатывать жизненный цикл плеера соответствующим образом, чтобы обрабатывать изменения конфигурации, а также приостанавливать и возобновлять активность.

Теперь просто вызовите эти методы жизненного цикла в соответствующем методе действия, фрагмента или Lifecycle Observer.

Ключевые выводы

  • ExoPlayer может поддерживать несколько видео и аудио форматов. (Проверьте раздел BuildMediaSource)
  • Поскольку Exoplayer поддерживает потоковую передачу с адаптивным битрейтом, вы можете использовать эту технику (используя источник мультимедиа DASH или HLS), чтобы улучшить взаимодействие с пользователем.
  • ExoPlayer предлагает множество полезных функций поверх встроенной библиотеки MediaCodec Android, что упрощает разработку более мощных и потрясающих видеоплееров.

Удачного кодирования!