Exoplayer的入门使用(kotlin)

  1. 首先,你需要导入ExoPlayer的包
implementation 'com.google.android.exoplayer:exoplayer:2.11.4'

我在此时查到的最新版的是2.11.4的,你们可以通过github获取到当前最新版本,地址:Exoplayer
再写出使用的仓库:

  repositories {
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public' } //添加这句,使用阿里云镜像
        google()
        jcenter()
        mavenCentral()
        maven { url 'https://maven.google.com' }
    }

此时进行rebuild你将报错,报错信息为:

Invoke-customs are only supported starting with Android O (--min-api 26)

你需要在让他支持java8,写在buiud.gradle(Module:app)中;

android {
	
 	buildTypes {。。。。。。省略不写}
 	
  	compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

到这里,前期工作就已经完成了,接下来就是使用了;

  1. 你需要一个播放器控件
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Activity.PlayerActivity"
    android:fitsSystemWindows="false">

    <com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/player_view"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        app:controller_layout_id="@layout/control_view"
        tools:ignore="MissingConstraints" />

</androidx.constraintlayout.widget.ConstraintLayout>

其中app:controller_layout_id="@layout/control_view"为我自定义了控制器(播放,暂停等),其中可以将不需要的控件进行删除,需要的控件(播放、暂停)等,你不能改变id;下面是自定义的播放控制器;如果你不需要自定义,将这句代码:app:controller_layout_id="@layout/control_view"删除即可,会使用默认的控制器;控制器的代码你可以通过全局搜索:exo_playback_control_view.xml拿到;

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:background="#A4000000"
    android:layoutDirection="ltr"
    android:orientation="vertical"
    tools:targetApi="28">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal"
        android:paddingTop="4dp">

        <ImageButton
            android:id="@id/exo_prev"
            style="@style/ExoMediaButton.Previous" />

        <ImageButton
            android:id="@id/exo_rew"
            style="@style/ExoMediaButton.Rewind" />

        <ImageButton
            android:id="@id/exo_shuffle"
            style="@style/ExoMediaButton" />

        <ImageButton
            android:id="@id/exo_repeat_toggle"
            style="@style/ExoMediaButton" />

        <ImageButton
            android:id="@id/exo_play"
            style="@style/ExoMediaButton.Play" />

        <ImageButton
            android:id="@id/exo_pause"
            style="@style/ExoMediaButton.Pause" />

        <ImageButton
            android:id="@id/exo_ffwd"
            style="@style/ExoMediaButton.FastForward" />

        <ImageButton
            android:id="@id/exo_next"
            style="@style/ExoMediaButton.Next" />

        <ImageButton
            android:id="@id/exo_vr"
            style="@style/ExoMediaButton.VR" />

        <TextView
            android:id="@+id/fullscreen"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="全屏"
            android:textColor="#FFFFFF"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <TextView
            android:id="@id/exo_position"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:includeFontPadding="false"
            android:paddingLeft="4dp"
            android:paddingRight="4dp"
            android:textColor="#FFBEBEBE"
            android:textSize="14sp"
            android:textStyle="bold" />

        <View
            android:id="@id/exo_progress_placeholder"
            android:layout_width="0dp"
            android:layout_height="26dp"
            android:layout_weight="1" />

        <TextView
            android:id="@id/exo_duration"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:includeFontPadding="false"
            android:paddingLeft="4dp"
            android:paddingRight="4dp"
            android:textColor="#FFBEBEBE"
            android:textSize="14sp"
            android:textStyle="bold" />

    </LinearLayout>

</LinearLayout>
  1. 接下来就是编写代码了,首先,你要播放一个视频,是不是需要一个媒体资源,那我们先写一个创建媒体资源的方法;
private fun createMediaSource(intent: Intent): MediaSource? {
		//首先你需要获取到Uri,我这里是通过另一个activity的intent传递过来的
        var videoUri: Uri = intent.getParcelableExtra("uri")
		//接下来你需要分析出你要播放的视频是什么格式的
        val type: Int = Util.inferContentType(videoUri)
        println("解析出的视频格式为 : $type")
		//这里的BassApplication是我自定义的application的名称
        var dataSourceFactory: DataSource.Factory =
            DefaultHttpDataSourceFactory(Util.getUserAgent(this, "BassApplication"))
        //接下来就是根据不同的视频格式,创建不同的MediaSource了
        return when (type) {
            C.TYPE_DASH ->
                DashMediaSource.Factory(dataSourceFactory).createMediaSource(videoUri)
            C.TYPE_SS ->
                SsMediaSource.Factory(dataSourceFactory).createMediaSource(videoUri)
            C.TYPE_HLS ->
                HlsMediaSource.Factory(dataSourceFactory).createMediaSource(videoUri)
            C.TYPE_OTHER ->
                ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(videoUri)
            else -> null
        }
    }
  1. 既然资源准备好了,那我们岂不是可以播放了?没错!你只需要再初始化一些东西即可;

首先,我们需要一个SimpleExoPlayer;
trackSelector,这个将用于打印debug的时候用的,Exoplayer支持你打印一些信息,以方便你调试使用;这里我们先初始化好;

 private var player: SimpleExoPlayer? = null
 private var trackSelector: DefaultTrackSelector? = null
 private var startAutoplay = true

接下来,我们来初始化player;

private fun initPlayer() {
        if (player == null) {
            trackSelector = DefaultTrackSelector(this)
            //初始化Exoplayer
            player = SimpleExoPlayer.Builder(this).build()
            //监听播放状态以及失败原因
            player!!.addListener(PlayerEventListener())
            //将错误信息打印出来
            player!!.addAnalyticsListener(EventLogger(trackSelector))
            //
            player!!.setAudioAttributes(
                AudioAttributes.DEFAULT, /* handleAudioFocus= */  /* handleAudioFocus= */
                true
            )
            //当他准备好资源后就播放
            player!!.playWhenReady = startAutoplay
            //这里是将player设置近player_view中
            player_view.player = player
            //
            player_view.setPlaybackPreparer(this)
        }
        //初始化完成后,我们就将资源设置近player中
        createMediaSource(intent)?.let { player!!.prepare(it) }
    }
    
    //这里监听到播放时的状态,以及获取到异常情况
private class PlayerEventListener : Player.EventListener {
        override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
            println("xxxxx  onPlayerStateChanged")
        }

        override fun onPlayerError(error: ExoPlaybackException) {
            if (error.type == ExoPlaybackException.TYPE_SOURCE) {
                val cause: IOException = error.sourceException
                if (cause is HttpDataSource.HttpDataSourceException) {
                    val httpError: HttpDataSource.HttpDataSourceException = cause
                    val dataSpec = httpError.dataSpec

                    if (httpError is HttpDataSource.InvalidResponseCodeException) {
                        // Cast to InvalidResponseCodeException and retrieve the response code,
                        // message and headers.
                    } else {
                        // Try calling httpError.getCause() to retrieve the underlying cause,
                        // although note that it may be null.
                    }
                }
            }
            println("xxxxxxxxxx   发生播放异常")
        }

        override fun onTracksChanged(
            trackGroups: TrackGroupArray,
            trackSelections: TrackSelectionArray
        ) {
            println("xxxxx  onTracksChanged")
        }
    }

  1. 接下来,我们就可以开始初始化了
@SuppressLint("SourceLockedOrientationActivity")
    override fun onStart() {
        super.onStart()
        //初始化player
        initPlayer()
        //让player_view准备好
        player_view?.onResume()
    }
  1. 到这里已经完成所有的初始化工作了,可以开始播放视频啦!只要你的Uri没有错,那么你在启动Activity后,将播放视频!当然,我这里的Uri是从网络获取到的,播放本地视频多没意思
  2. 请注意,还有最后一点,你需要释放player,否则,后果就难以想象咯!
private fun releasePlayer() {
        if (player != null) {
            player!!.release()
            player = null
            trackSelector = null
        }
    }
    
 override fun onDestroy() {
        super.onDestroy()
        releaseAdsLoader()
        releasePlayer()
    }
  1. 本文章中实现的只是非常简单的功能,Exoplayer可不止这么简单,它还有各种花里胡哨的功能我也没有摸清,你也可以查看文档去了解更多的信息 ------->文档地址
    接下来我也会继续去摸索Exoplayer,了解更多信息,然后通过文章的方式再描述出来,方便自己在以后忘了的时候也可以查看文章;

你可能感兴趣的:(Android)