OpenDanmaku实现弹幕效果
16lz
2021-01-26
一、OpenDanmaku简介
1.OpenDanmaku介绍
OpenDanmaku是Android中第三方的弹幕控件,在播放视频和直播软件中过程中弹出用户的评论,并且以滚动的方式显示。
2.下载地址
https://github.com/linsea/OpenDanmaku
3.项目依赖
Gradle dependencies { compile 'com.linsea:opendanmaku:[email protected]' }//或者引用本地libcompile project(':opendanmaku')
二、OpenDanmaku使用步骤
1.布局文件
2.弹幕逻辑代码
import com.opendanmaku.DanmakuItem;import com.opendanmaku.DanmakuView;import com.opendanmaku.IDanmakuItem;import java.util.ArrayList;import java.util.Collections;import java.util.List;public class OpendanmakuMainActivity extends AppCompatActivity implements View.OnClickListener{ private DanmakuView mDanmakuView; private Button switcherBtn; private Button sendBtn; private EditText textEditText; private TextView tv_title; private VideoView videoView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_opendanmaku_main); tv_title = (TextView) findViewById(R.id.tv_title); tv_title.setText("Opendanmaku弹幕"); //实例化控件 mDanmakuView = (DanmakuView) findViewById(R.id.danmakuView); switcherBtn = (Button) findViewById(R.id.switcher); sendBtn = (Button) findViewById(R.id.send); textEditText = (EditText) findViewById(R.id.text); videoView = (VideoView) findViewById(R.id.videoView); setVideoView(); //添加弹幕集合数据 List list = initItems(); //把数据进行随机排列 Collections.shuffle(list); //添加到弹幕控件上 mDanmakuView.addItem(list, true); switcherBtn.setOnClickListener(this); sendBtn.setOnClickListener(this); } private void setVideoView() { videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { videoView.start(); } }); videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { videoView.start(); } });// videoView.setVideoPath("http://10.0.2.2:8080/mp4/161122105613271790_480.mp4"); videoView.setVideoPath("http://10.0.2.2:8080/oppo.mp4"); videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { Toast.makeText(OpendanmakuMainActivity.this, "您的手机不支持播放该视频", Toast.LENGTH_SHORT).show(); return true; } }); videoView.setMediaController(new MediaController(this)); } private List initItems() { List list = new ArrayList<>(); for (int i = 0; i < 100; i++) { IDanmakuItem item = new DanmakuItem(this, i + " : plain text danmuku", mDanmakuView.getWidth()); list.add(item); } String msg = " : text with image "; for (int i = 0; i < 100; i++) { ImageSpan imageSpan = new ImageSpan(this, R.drawable.em); SpannableString spannableString = new SpannableString(i + msg); spannableString.setSpan(imageSpan, spannableString.length() - 2, spannableString.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); IDanmakuItem item = new DanmakuItem(this, spannableString, mDanmakuView.getWidth(), 0, 0, 0, 1.5f); list.add(item); } return list; } @Override protected void onResume() { super.onResume(); mDanmakuView.show(); } @Override protected void onPause() { super.onPause(); //隐藏 mDanmakuView.hide(); } @Override protected void onDestroy() { super.onDestroy(); //清除 mDanmakuView.clear(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.switcher: if (mDanmakuView.isPaused()) { switcherBtn.setText(R.string.hide); mDanmakuView.show(); } else { switcherBtn.setText(R.string.show); mDanmakuView.hide(); } break; case R.id.send: String input = textEditText.getText().toString(); if (TextUtils.isEmpty(input)) { Toast.makeText(OpendanmakuMainActivity.this, R.string.empty_prompt, Toast.LENGTH_SHORT).show(); } else { IDanmakuItem item = new DanmakuItem(this, new SpannableString(input), mDanmakuView.getWidth(),0,R.color.my_item_color,0,1);// IDanmakuItem item = new DanmakuItem(this, input, mDanmakuView.getWidth());// item.setTextColor(getResources().getColor(R.color.my_item_color));// item.setTextSize(14);// item.setTextColor(textColor); mDanmakuView.addItemToHead(item); } textEditText.setText(""); break; } }}
3.在视频上用OpenDanmaku显示弹幕
设置视频路径:http://api.m.mtime.cn/PageSubArea/TrailerList.api
4.解决弹幕把视频遮挡的问题
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (status == STATUS_RUNNING) { try {// canvas.drawColor(Color.TRANSPARENT); canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); //先绘制正在播放的弹幕 for (int i = 0; i < mChannelMap.size(); i++) { ArrayList list = mChannelMap.get(i); for (Iterator it = list.iterator(); it.hasNext(); ) { IDanmakuItem item = it.next(); if (item.isOut()) { it.remove(); } else { item.doDraw(canvas); } } } //检查是否需要加载播放下一个弹幕 if (System.currentTimeMillis() - previousTime > mPickItemInterval) { previousTime = System.currentTimeMillis();// Log.d(TAG, "start pick new item.."); IDanmakuItem di = mWaitingItems.pollFirst(); if (di != null) { int indexY = findVacant(di); if (indexY >= 0) {// Log.d(TAG, "find vacant channel"); di.setStartPosition(canvas.getWidth() - 2, mChannelY[indexY]);// Log.d(TAG, "draw new, text:" + di.getText()); //Log.d(TAG, String.format("doDraw, position,x=%s,y=%s", c.getWidth() - 1, mChannelY[indexY])); di.doDraw(canvas); mChannelMap.get(indexY).add(di);//不要忘记加入正运行的维护的列表中 } else {// Log.d(TAG, "Not find vacant channel, add it back"); addItemToHead(di);//找不到可以播放的弹道,则把它放回列表中 } } else { //no item 弹幕播放完毕, } } if (mShowDebug) { int fps = (int) fps(); canvas.drawText("FPS:" + fps, 5f, 20f, fpsPaint); for (float yp : lines) { canvas.drawLine(0f, yp, getWidth(), yp, fpsPaint); } } } catch (Exception e) { e.printStackTrace(); } invalidate(); } else {//暂停或停止,隐藏弹幕内容 canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); } }
看到此,是不是接的OpenDanmaku的简单使用是不是很简单,谢谢浏览!
更多相关文章
- Android(安卓)Material Design控件之FloatingActionButton
- Android自定义UI实战(基础篇1)---组合控件封装
- Android-Module:ToggleButton常用XML属性
- Android实现Tab布局的4种方式(Fragment+TabPageIndicator+ViewPag
- 【Android】5.3 单选和复选
- Android(安卓)如何通过menu id来得到menu item 控件--binbinyang
- Android(安卓)实现适配器中的子控件与Activity通信
- Android锁屏界面控制音乐播放
- 更改Android(安卓)AppCompatRadioButton控件的样式和颜色