Android 集成 ijkplayer 播放器 + 封装实践(控制栏 / 倍速 / 全屏)
最近项目中用到了在线视频播放功能,在调研了 ExoPlayer、VLC、ijkplayer 后,最终选择了 Bilibili 开源的 ijkplayer —— 功能强大,FFmpeg 底层支持全面,关键是还支持直播流、软/硬解切换、流式播放等特性。
本文分享我在项目中:
- 如何 快速引入 ijkplayer;
- 如何自定义播放器组件(控制栏、倍速、全屏);
- 踩坑 & 性能优化经验。
一、ijkplayer 快速集成
1. 添加依赖
项目根目录 settings.gradle:
1 2 3 4 5 6 7 8 9 10 11
| groovy
复制编辑 dependencyResolutionManagement { repositories { google() mavenCentral() maven { url "https://jitpack.io" } } }
|
模块 app/build.gradle:
1 2 3 4 5 6 7 8
| groovy
复制编辑 dependencies { implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8' implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8' }
|
二、基础播放功能实现
1. 初始化(建议在 Application)
1 2 3 4 5 6 7 8 9 10 11 12
| java
复制编辑 public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); IjkMediaPlayer.loadLibrariesOnce(null); IjkMediaPlayer.native_profileBegin("libijkplayer.so"); } }
|
2. 播放器布局
1 2 3 4 5 6 7 8
| xml
复制编辑 <tv.danmaku.ijk.media.widget.IjkVideoView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="match_parent" />
|
3. 开始播放
1 2 3 4 5 6 7
| java
复制编辑 IjkVideoView videoView = findViewById(R.id.video_view); videoView.setVideoPath("https://your.domain.com/video.mp4"); videoView.start();
|
三、自定义播放器封装(控制栏 + 倍速 + 全屏)
下面是我封装的简易播放器组件结构:
1 2 3 4 5
| 复制编辑 PlayerContainer(FrameLayout) │ ├── IjkVideoView (播放器) ├── PlayerControllerView(控制栏)
|
1. 控制栏布局(player_controller_view.xml)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| xml
复制编辑 <LinearLayout android:id="@+id/controller_root" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:orientation="horizontal" android:background="#99000000">
<ImageButton android:id="@+id/btn_play_pause" android:src="@drawable/ic_play" ... />
<SeekBar android:id="@+id/seek_bar" ... />
<TextView android:id="@+id/speed_text" android:text="1.0x" ... />
<ImageButton android:id="@+id/btn_fullscreen" android:src="@drawable/ic_fullscreen" ... /> </LinearLayout>
|
2. 控制逻辑(PlayerControllerView.java)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| java
复制编辑 btnPlayPause.setOnClickListener(v -> { if (videoView.isPlaying()) { videoView.pause(); btnPlayPause.setImageResource(R.drawable.ic_play); } else { videoView.start(); btnPlayPause.setImageResource(R.drawable.ic_pause); } });
speedText.setOnClickListener(v -> { currentSpeed = (currentSpeed >= 2.0f) ? 1.0f : currentSpeed + 0.5f; speedText.setText(currentSpeed + "x"); if (videoView.getMediaPlayer() instanceof IjkMediaPlayer) { ((IjkMediaPlayer) videoView.getMediaPlayer()).setSpeed(currentSpeed); } });
btnFullscreen.setOnClickListener(v -> { // 可切换横屏或使用 Dialog 全屏方案 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); });
|
四、播放参数优化建议
1 2 3 4 5 6 7 8
| java
复制编辑 videoView.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1); // 开启硬解 videoView.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http-detect-range-support", 0); videoView.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1); videoView.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", 100);
|
🔐 五、混淆配置(ProGuard)
1 2 3 4 5 6
| pro
复制编辑 -keep class tv.danmaku.ijk.media.** { *; } -dontwarn tv.danmaku.ijk.media.**
|
六、常见问题排查
| 问题 |
解决建议 |
| 播放黑屏 |
检查是否支持硬解/软解,或设置了合适的 start-on-prepared |
| 播放失败 |
视频链接是否支持 HTTP Range;可能需要自定义 header |
| 倍速无效 |
必须使用 IjkMediaPlayer 实例并确保 FFmpeg 支持时间拉伸 |
| 播放卡顿 |
开启硬解、丢帧、降低分辨率尝试优化 |
七、项目结构推荐封装方式
你可以将播放器封装为组件使用,例如:
IjkPlayerView: 封装了 IjkVideoView + Controller 控件;
IjkPlayerManager: 封装播放器生命周期(播放、暂停、销毁);
IjkPlayerUtils: 提供 URL 校验、加载监听、错误处理等辅助方法。
八、参考资料
总结一下
- ijkplayer 适合复杂流媒体播放场景,尤其是直播/流式点播;
- 可灵活切换软/硬解,播放控制细粒度高;
- 封装控制栏不难,可灵活扩展倍速、全屏、进度、手势等功能;
- 如果只做本地/MP4 播放,ExoPlayer 也是不错的轻量级选择。