开源视频播放器IjkPlayer使用记录之一--demo的使用及View的简要介绍

本文介绍Ijkplayer作为一款轻量级Android/iOS视频播放器的优势,包括其支持广泛的ffmpeg编码格式。文章详细讲解了如何编译所需的so库、集成Ijkplayer到项目中并解析IjkVideoView的基本架构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.初识Ijkplayer

Android系统提供的MediaPlayer支持的编码格式有限,这里推荐一款开源的媒体播放器Ijkplayer.

ijkplayer 是一个基于 ffplay 的轻量级 Android/iOS 视频播放器。

对应的git路径:https://github.com/Bilibili/ijkplayer

在Android端,基本上还是沿用SurfaveView+MediaController的架构。就是将MediaPlayer替换成Ijkplayer,支持 ffmpeg的各种编码方式。

2.依赖so的编译

需要准备的工具链:NDK,目前最近的分支已经支持ndk13,android studio或者是官网可以下载到该版本。

个人使用的编译方法是git取源码,在mac上进行编译,然后再把编译好的so放到对应的项目中去。

从git说明的Before Build一步一步操作到buuld android 就可以编译出对应的so文件。

3.使用demo

步骤:1.把编译好的so放到jni对应的目录。

  2.编译ijkplayer-java,已aar的方式导入项目(ps:我是直接copy源码到项目自己编译)

  3.将example中的widget目录和service目录导入项目。

  4.创建自己的activity,使用example中的IjkVideoView来播放。

需要注意的是这种导入方法,需要手动需要res中的string,color,layout等内容,选择性的导入项目。


我本地做的时候把hubview给砍了。

初始化mediaplayer,绑定mediaController,开启video就好了。

 // init player
        IjkMediaPlayer.loadLibrariesOnce(null);
        IjkMediaPlayer.native_profileBegin("libijkplayer.so");

        videoView = (IjkVideoView) findViewById(R.id.video_view);
   videoView.setMediaController(mMediaController);
 videoView.setVideoURI(Uri.parse(inputUrl));
        videoView.start();

4.介绍一下IjkVideoView的基础架构。

个人理解理顺MediaPlayer,SurfaceView,MediaController这3个资源的关系,这个代码也就比较清晰了:

        这里使用setVideoURI的流程来做说明。

Step1  IjkVideoView初始化

initBackground();//支持后台播放时的初始化。
    initRenders();//初始化surfaceview界面资源

Step2 setViedoURI

来看一下openVideo的源码
AudioManager am = (AudioManager) mAppContext.getSystemService(Context.AUDIO_SERVICE);
am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);

try {
    mMediaPlayer = createPlayer(mSettings.getPlayer());//mediaPlayer 初始化配置。

    // TODO: create SubtitleController in MediaPlayer, but we need
    // a context for the subtitle renderers
    final Context context = getContext();
    // REMOVED: SubtitleController

    // REMOVED: mAudioSession
    mMediaPlayer.setOnPreparedListener(mPreparedListener);  //Onprepared回调。mediaplayer的流程可以看官网doc的说明。下面的类似。
    mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener) //surfaceview图片大小变更回调,ffplay的回调。
    mMediaPlayer.setOnCompletionListener(mCompletionListener); 
    mMediaPlayer.setOnErrorListener(mErrorListener);
    mMediaPlayer.setOnInfoListener(mInfoListener);	
    mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener); 
    mMediaPlayer.setOnSeekCompleteListener(mSeekCompleteListener);
    mCurrentBufferPercentage = 0;
    String scheme = mUri.getScheme();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
            mSettings.getUsingMediaDataSource() &&
            (TextUtils.isEmpty(scheme) || scheme.equalsIgnoreCase("file"))) {
        IMediaDataSource dataSource = new FileMediaDataSource(new File(mUri.toString()));
        mMediaPlayer.setDataSource(dataSource);
    }  else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        mMediaPlayer.setDataSource(mAppContext, mUri, mHeaders);
    } else {
        mMediaPlayer.setDataSource(mUri.toString());
    }
    bindSurfaceHolder(mMediaPlayer, mSurfaceHolder);   //mediaplayer绑定surfaceview.
    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mMediaPlayer.setScreenOnWhilePlaying(true);
    mPrepareStartTime = System.currentTimeMillis();
    mMediaPlayer.prepareAsync();
    if ((mHudViewHolder != null) && (mSettings.getEnableBackgroundPlay()))
        mHudViewHolder.setMediaPlayer(mMediaPlayer);

    // REMOVED: mPendingSubtitleTracks

    // we don't set the target state here either, but preserve the
    // target state that was there before.
    mCurrentState = STATE_PREPARING;
    attachMediaController();	//mediaplayer绑定mediacontrol.
} catch (IOException ex) {
    Log.w(TAG, "Unable to open content: " + mUri, ex);
    mCurrentState = STATE_ERROR;
    mTargetState = STATE_ERROR;
    mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
} catch (IllegalArgumentException ex) {
    Log.w(TAG, "Unable to open content: " + mUri, ex);
    mCurrentState = STATE_ERROR;
    mTargetState = STATE_ERROR;
    mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
} finally {
    // REMOVED: mPendingSubtitleTracks.clear();
}
后面就是处理各种回调。
第一篇先到这里,后续边学边补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值