ijkPlayer集成笔记(一)

从jjkPlayer的github地址把官方的项目down下来。本文参考的版本是0.8.4。

copy “..\ijkplayer-master\android\ijkplayer\ijkplayer-example\src\main\java\tv\danmaku\ijk\media\example\widget\media”这个media文件夹到自己的项目里。

在builder.gradle里面添加如下的代码:

compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.4'
compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.4'

如果需要其他的abi在导入其他的库,一般armv7a就足够了。

关键是参考IjkVideoView这个类里面的代码。

官方的IjkVideoView是支持列表视频的,本次集成只播放单个视频。所以重新创建一个类去实现,大概的思路跟IjkVideoView一样,本文就命名为IVideoView。

不需要Settings相关的代码,后面涉及到Settings的代码,都去掉。

基本步骤如下:

  1. initBackground方法不需要,不需要后台播放;
  2. initRenders方法是切换渲染的控件,直接采用SurfaceView,去掉这个方法直接使用其调用的setRender方法;
  3. 在setRender调用了setRenderView的方法,我们将setRenderView里面的代码直接放到setRender方法里,去掉setRenderView方法;
  4. 去掉initVideoView中创建标题的代码,那么initVideoView这个方法就改造完了;
  5. copy设置URI的方法,不需要设置列表的方法;
  6. copy openVideo的方法;
  7. openVideo里面有个createVideo的方法,这个方法里面我们需要整理一番,里面Settings的方法比较多;
    把openVideo里面调用createVideo方法后面的代码也移到createVideo方法里面,改完的代码如下:
/**
     * 初始化播放器
     */
    private void createPlayer() {
        try {
            mMediaPlayer = new IjkMediaPlayer();
            //设置日志类型
            mMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_ERROR);
            //设置为软解码 ijk是基于FFmpeg的,采用软解,此处待定
            mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 0);
            //opensles:嵌入式音频加速标准 设置为默认支持
            mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 1);
            //域名检测
            mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http-detect-range-support", 0);

            mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32);
            mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1);
            mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0);
//            mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "analyzeduration", "2000000");
//            mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "probsize", "4096");
            mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);

            //设置视频初始化的监听
            /**
             * @see #setOnPreparedListener(IMediaPlayer.OnPreparedListener)
             */
            mMediaPlayer.setOnPreparedListener(mPreparedListener);
            /**
             * @see #setOnCompletionListener(IMediaPlayer.OnCompletionListener)
             */
            mMediaPlayer.setOnCompletionListener(mCompletionListener);
            /**
             * @see #setOnErrorListener(IMediaPlayer.OnErrorListener)
             */
            mMediaPlayer.setOnErrorListener(mErrorListener);
            /**
             * @see #setOnInfoListener(IMediaPlayer.OnInfoListener)
             */
            mMediaPlayer.setOnInfoListener(mInfoListener);

            mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
            //当前加载的视频流百分比
            mCurrentBufferPercentage = 0;
            //版本在4.0以上和4.0以下设置方式
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                mMediaPlayer.setDataSource(mAppContext, mUri, null);
            } else {
                mMediaPlayer.setDataSource(mUri.toString());
            }
            bindSurfaceHolder(mMediaPlayer, mSurfaceHolder);
            //设置流的类型
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            //屏幕常亮
            mMediaPlayer.setScreenOnWhilePlaying(true);

            mMediaPlayer.setLooping(loop);
            mMediaPlayer.prepareAsync();

            mCurrentState = STATE_PREPARING;
            attachMediaController();
        } catch (IOException e) {
//            Log.w(TAG, "Unable to open content: " + mUri, e);
            mCurrentState = STATE_ERROR;
            mTargetState = STATE_ERROR;
            mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
//            e.printStackTrace();
        } finally {

        }
    }
  1. 各种监听事件直接copy一波,监听事件里面需要调用的方法copy一波;
  2. realse方法直接copy;
  3. 各种状态转换方法里面的内容直接copy;
  4. 删除不必要的类,最终media包里面的类如下:
简化代码后的media包

到这里轮子就基本创建好了。

接着就是写符合自己需求的控制器代码了。
ijkPlayer集成笔记(二)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1 背景 公司的底层播放器实际上是ffplayer作为基础修改的,当然需要好好学习研究。 记录下来,作为以后备忘。...
    nothingwxq阅读 4,412评论 4 5
  • 1.OC里用到集合类是什么? 基本类型为:NSArray,NSSet以及NSDictionary 可变类型为:NS...
    轻皱眉头浅忧思阅读 1,394评论 0 3
  • 本文记录的是ijkplayer的初始化流程(重点在分析底层c代码的逻辑),为了更好的理解这部分内容,建议大家下载i...
    ce0b74704937阅读 3,113评论 0 1
  • 随着互联网技术的飞速发展,移动端播放视频的需求如日中天,由此也催生了一批开源/闭源的播放器,但是无论这个播放器功能...
    金山视频云阅读 46,495评论 28 170
  • 上面这个工作属于财务工作的基本功之一,以前都是我交别人做。从东北回来之后一直一个人抓弄工作,没找个学徒也没...
    栗花香阅读 585评论 18 15