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 也是不错的轻量级选择。