ijkplayer 简单使用

1,476 阅读2分钟

添加依赖

 api 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8

倒入so文件 自行编译下载

ijkffmpeg.so
ijksdl.so
ijkplayer.so

//初始化SurfaceTexture


var textureView: TextureView? = null

fun  addTextureView() {
    if (textureView != null) mBinding.surfaceContainer.removeView(textureView)
    textureView =  TextureView(requireContext())
    textureView?.surfaceTextureListener = object : TextureView.SurfaceTextureListener {
        override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int) {
                //在这里初始化播放器
                initPlayer()
        }

        override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) {}

        override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
            return false
        }
        override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {
        }
    }

    var layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER)
    mBinding.surfaceContainer.addView(textureView, layoutParams)
 }



//初始化 IjkMediaPlayer

fun initPlayer(){

    ijkMediaPlayer =  IjkMediaPlayer()

    ijkMediaPlayer?.setAudioStreamType(AudioManager.STREAM_MUSIC)
    ////1为硬解 0为软解
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 0)
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1)
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 1)
    //使用opensles把文件从java层拷贝到native层
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 0)
    //视频格式
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32.toLong())
    //跳帧处理(-1~120)。CPU处理慢时,进行跳帧处理,保证音视频同步
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1)
    //0为一进入就播放,1为进入时不播放
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0)
    ////域名检测
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http-detect-range-support", 0)
    //设置是否开启环路过滤: 0开启,画面质量高,解码开销大,48关闭,画面质量差点,解码开销小
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48)
    //最大缓冲大小,单位kb
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-buffer-size", 1024 * 1024)
    //某些视频在SeekTo的时候,会跳回到拖动前的位置,这是因为视频的关键帧的问题,通俗一点就是FFMPEG不兼容,视频压缩过于厉害,seek只支持关键帧,出现这个情况就是原始的视频文件中i 帧比较少
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1)
    //是否重连
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "reconnect", 1)
    //http重定向https
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_clear", 1)
    //设置seekTo能够快速seek到指定位置并播放
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "fflags", "fastseek")
    //播放前的探测Size,默认是1M, 改小一点会出画面更快
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 1024 * 10)
    //1变速变调状态 0变速不变调状态
    ijkMediaPlayer?.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "soundtouch", 1)

    try {
        var urlPlay ="https://media.w3.org/2010/05/sintel/trailer.mp4"
        ijkMediaPlayer?.setDataSource(urlPlay)
        ijkMediaPlayer?.setAudioStreamType(AudioManager.STREAM_MUSIC)
        ijkMediaPlayer?.setScreenOnWhilePlaying(true)
        ijkMediaPlayer?.prepareAsync()
        ijkMediaPlayer?.setSurface( Surface(textureView?.surfaceTexture))
        ijkMediaPlayer?.setOnPreparedListener(object: IMediaPlayer.OnPreparedListener{
            override fun onPrepared(p0: IMediaPlayer?) {
                ijkMediaPlayer?.start()
            }

        })

    } catch ( e: IOException) {
        e.printStackTrace()
    }

}

//xml布局


<FrameLayout
    android:id="@+id/surface_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</FrameLayout>