IJKPlayer 播放视频

作者: JinYx | 来源:发表于2019-09-29 13:16 被阅读0次

      本篇内容将介绍 IJKPlayer 播放器在 Android 中的使用

    一、导入依赖库

        // required, enough for most devices.
        api 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
        api 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
        // Other ABIs: optional
        api 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8'
        api 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8'
        api 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8'
        api 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8'
        // ExoPlayer as IMediaPlayer: optional, experimental
        api 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8'
    

    二、查看官方 Demo

    图1. IJK 官方播放器 Demo

    三、重写 MediaController 实现自己需要的效果

    1. IJKPlayer 的使用

       IJKPlayer 播放使用到了上面 Demo 中的 IjkVideoView, 给 IjkVideoView 设置一个 Controller,调用 setVideoPath 设置播放链接,再执行 start 方法开始播放视频即可;不过使用其原来的 AndroidMediaController,效果很差,所以需要重写;

        private var mController: AndroidMediaController? = null
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_video)
    
            mController = AndroidMediaController(this)
            mController!!.setSupportActionBar(txtTitle)
            player?.setMediaController(mController)
            player?.setVideoPath("http://baobab.kaiyanapp.com/api/v1/playUrl?vid=66073&editionType=high&source=aliyun")
            player?.setOnErrorListener(this)
            player?.setOnCompletionListener(this)
            player?.start()
        }
    

    2. 重写 AndroidMediaController

      AndroidMediaController 继承自MediaController,所以我们可以按照 MediaController 的模式,写一个自己的 Controller 给 AndroidMediaController 继承;
       首先是 initFloatingWindow 方法中,实例化 Window 的处理,Window 对应唯一一个 PhoneWindow,却是系统的隐藏Api,只能通过反射的方式获取实例;反射的时候需要注意一点:

    Android 5.1 及之前是使用 PolicyManager.makeNewWindow(context) 创建的 PhoneWindow;
    Android 5.1 之后是通过 new PhoneWindow(context) 创建的 PhoneWindow;

       两种方式对应的 PhoneWindow 的路径并不相同,所以反射代码如下:

     private void initFloatingWindow() {
            mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
            try {
                Class<?> clazz;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    clazz = Class.forName("com.android.internal.policy.PhoneWindow");
                } else {
                    clazz = Class.forName("com.android.internal.policy.impl.PhoneWindow");
                }
                Constructor constructor = clazz.getDeclaredConstructor(Context.class);
                constructor.setAccessible(true);
                mWindow = (Window) constructor.newInstance(mContext);
            } catch (Exception e) {
                e.printStackTrace();
                if (mContext instanceof Activity) {
                    mWindow = ((Activity) mContext).getWindow();
                }
            }
            mWindow.setWindowManager(mWindowManager, null, null);
            mWindow.requestFeature(Window.FEATURE_NO_TITLE);
            mDecor = mWindow.getDecorView();
            mDecor.setOnTouchListener(mTouchListener);
            mWindow.setContentView(this);
            mWindow.setBackgroundDrawableResource(android.R.color.transparent);
    
            // While the media controller is up, the volume control keys should
            // affect the media stream type
            mWindow.setVolumeControlStream(AudioManager.STREAM_MUSIC);
    
            setFocusable(true);
            setFocusableInTouchMode(true);
            setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
            requestFocus();
        }
    

       再来是 makeControllerView 方法中,定义各自需要的 UI 效果,

        private void initControllerView(View v) {
            Resources res = mContext.getResources();
            mPlayDescription = res.getText(R.string.lockscreen_transport_play_description);
            mPauseDescription = res.getText(R.string.lockscreen_transport_pause_description);
    
            mRelativeVideo = v.findViewById(R.id.relativeVideo);
            if (mRelativeVideo != null) {
                mRelativeVideo.setOnClickListener(mRelativeVideoClick);
            }
    
            mPauseButton = v.findViewById(R.id.imgPlay);
            if (mPauseButton != null) {
                mPauseButton.requestFocus();
                mPauseButton.setOnClickListener(mPauseListener);
            }
    
            mProgress = v.findViewById(R.id.seekVideo);
            if (mProgress != null) {
                if (mProgress instanceof SeekBar) {
                    SeekBar seeker = (SeekBar) mProgress;
                    seeker.setOnSeekBarChangeListener(mSeekListener);
                }
                mProgress.setMax(1000);
            }
    
            mEndTime = v.findViewById(R.id.txtDuration);
            mCurrentTime = v.findViewById(R.id.txtCurrentTime);
            mFormatBuilder = new StringBuilder();
            mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
        }
    

       注意如果不重写 Error 监听器,IJKPlayer 在播放出错的时候将会弹出一个很丑的弹窗,并且点击弹窗的确认,调用了 onComplete() 方法

    四、最后

       Demo 的效果图如下,如果需要看源码的,可以转到 GitHub

    图2. 效果图

    相关文章

      网友评论

        本文标题:IJKPlayer 播放视频

        本文链接:https://www.haomeiwen.com/subject/lgtoyctx.html