IjkPlayer是B站开源的项目,很多年了。这次记录一下我再4.4上使用的用的坑。
显示引入支持
implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
implementation 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8'
implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
implementation 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8'
implementation 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8'
implementation 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8'
上面会有两个地方
- 有两个64的扩展被我注释掉了,因为我的4.4好像不支持64位CPU?不注释掉,Build的时候会爆红,过不去。
- 要在库配置里增加
jcenter() 。就是google() 和mavenCentral() 的那个配置文件。settings.gradle
在layout文件中先写入一个SurfaceView控件
<SurfaceView
android:id="@+id/sv_camera"
android:layout_width="match_parent"
android:layout_height="520dp"/>
就当个普通的View控件来设置就好了,没有什么特别的。 这个控件将会被当做视频播放的容器来使用(也可以理解成视口,搞过Canvas的会很容易理解)。
为SurfaceView设置生命周期方法
svCamera = findViewById(R.id.sv_camera);
svCamera.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
ijkMediaPlayer = new IjkMediaPlayer();
IjkMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_DEBUG);
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
ijkMediaPlayer.release();
}
});
在要放播放器的Activity的onCreate方法中初始化播放器
IjkMediaPlayer ijkMediaPlayer = new IjkMediaPlayer();
IjkMediaPlayer .native_setLogLevel(IjkMediaPlayer.IJK_LOG_DEBUG);
在播放按钮事件中配置并播放流
ijkMediaPlayer.reset();
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
try {
ijkMediaPlayer.setDataSource("http://xxx/xxx.flv");
} catch (IOException e) {
e.printStackTrace();
}
ijkMediaPlayer.prepareAsync();
在停止播放按钮上增加STOP方法的调用即可
ijkMediaPlayer.stop();
这个释放播放器资源 前边已经调用了
ijkMediaPlayer.release();
上面的代码,是经过十几次试错之后,才成功的。都是弯路。虽然是很老的播放器,但是仍然很好用。从网上搜到的资料,大部分播放器都是几年前的代码,近两年都没有什么新鲜的东西出来。
下面贴一下最终实现的代码
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
public class WashesShoesActivity extends MainActivity {
private static final String TAG = "WashesShoesActivity";
LinearLayout llHeadBox,llMsgBox, llOrderBox;
FrameLayout flLiveBox;
TextView tvLiveState;
SurfaceView svCamera;
Button btnLiveFull, btnLiveStart;
IjkMediaPlayer ijkMediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.activity_washes_shoes);
llHeadBox = findViewById(R.id.ll_head_box);
llMsgBox = findViewById(R.id.ll_msg_box);
llOrderBox = findViewById(R.id.ll_order_box);
flLiveBox = findViewById(R.id.fl_live_box);
btnLiveFull = findViewById(R.id.btn_live_full);
btnLiveFull.setOnClickListener(view-> changeLiveFull());
tvLiveState = findViewById(R.id.tv_live_state);
tvLiveState.setTextColor(getResources().getColor(R.color.white));
tvLiveState.setText(R.string.is_not_live);
btnLiveStart = findViewById(R.id.btn_live_start);
btnLiveStart.setOnClickListener(view-> changeLiveStatus());
svCamera = findViewById(R.id.sv_camera);
svCamera.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
ijkMediaPlayer = new IjkMediaPlayer();
IjkMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_DEBUG);
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
ijkMediaPlayer.release();
}
});
}
private void changeLiveFull(){
ViewGroup.LayoutParams layoutParams = flLiveBox.getLayoutParams();
if (layoutParams.width == 640){
llHeadBox.setVisibility(ViewGroup.GONE);
llMsgBox.setVisibility(ViewGroup.GONE);
llOrderBox.setVisibility(ViewGroup.GONE);
layoutParams.width = 1024;
layoutParams.height = 768;
btnLiveFull.setText(R.string.btn_live_ori);
}else{
llHeadBox.setVisibility(View.VISIBLE);
llMsgBox.setVisibility(View.VISIBLE);
llOrderBox.setVisibility(View.VISIBLE);
layoutParams.width = 640;
layoutParams.height = 360;
btnLiveFull.setText(R.string.btn_live_full);
}
flLiveBox.setLayoutParams(layoutParams);
}
private void changeLiveStatus(){
if (!ijkMediaPlayer.isPlaying()) {
mLiveStatus = true;
ijkMediaPlayer.reset();
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
ijkMediaPlayer.setVolume(0.0F, 0.0F);
ijkMediaPlayer.setDisplay(svCamera.getHolder());
try {
ijkMediaPlayer.setDataSource("http://114.117.1.115:8080/live/livestream/office.flv");
ijkMediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
tvLiveState.setTextColor(getResources().getColor(R.color.yellow));
tvLiveState.setText(R.string.is_live);
btnLiveStart.setText(R.string.btn_live_stop);
}else{
mLiveStatus = false;
ijkMediaPlayer.stop();
tvLiveState.setTextColor(getResources().getColor(R.color.white));
tvLiveState.setText(R.string.is_not_live);
btnLiveStart.setText(R.string.btn_live_start);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
KeyInput.press(keyCode, event, KeyInput.Type.ALL);
return true;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
KeyInput.press(keyCode, event, KeyInput.Type.ALL);
return true;
}
}
上述代码仅供参考,最终还是封装成一个工具类或者是一个自定义控件,应该用起来会更舒服一些。
|