B站的DanmakuFlameMaster的使用

汪欣德
2023-12-01

B站的DanmakuFlameMaster的使用

B站的DanmakuFlameMaster的下载地址:https://github.com/Bilibili/DanmakuFlameMaster     点击打开链接


1、弹幕内容解析
DanmakuLoaderFactory.create(DanmakuLoaderFactory.TAG_BILI) //xml解析
DanmakuLoaderFactory.create(DanmakuLoaderFactory.TAG_ACFUN) //json文件格式解析


2、初始化
(1)弹幕view
 DanmakuGlobalConfig.DEFAULT.setDanmakuStyle(DanmakuGlobalConfig.DANMAKU_STYLE_STROKEN, 3)
        .setDuplicateMergingEnabled(false) //是否合并重复弹幕
        .setMaximumVisibleSizeInScreen(80) //同屏最大显示数量(弹幕密度(只对滚动有效))
        .setCacheStuffer(new BackgroundCacheStuffer());
        if (mDanmakuView != null) {
           mParser = createParser(this.getResources().openRawResource(R.raw.comments));
           
//           try {
// mParser = createParser(this.getResources().getAssets().open("comment.json"));
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
           mDanmakuView.setCallback(new Callback() {
                @Override
                public void updateTimer(DanmakuTimer timer) {
                }


                @Override
                public void prepared() {
                    mDanmakuView.start(); //开始播放
                }
            });
            mDanmakuView.prepare(mParser);
            mDanmakuView.showFPS(true);//是否显示fps
            mDanmakuView.enableDanmakuDrawingCache(false); //true在模拟器上运行有问题
            
private BaseDanmakuParser createParser(InputStream stream) {


        if (stream == null) {
            return new BaseDanmakuParser() {


                @Override
                protected Danmakus parse() {
                    return new Danmakus();
                }
            };
        }



(2)内容解析
        ILoader loader = DanmakuLoaderFactory.create(DanmakuLoaderFactory.TAG_BILI);


        try {
            loader.load(stream);
        } catch (IllegalDataException e) {
            e.printStackTrace();
        }
        BaseDanmakuParser parser = new BiliDanmukuParser();
        IDataSource<?> dataSource = loader.getDataSource();
        parser.load(dataSource);
        return parser;
    }

(3)弹幕背景和边距
private static class BackgroundCacheStuffer extends SpannedCacheStuffer {
        // 通过扩展SimpleTextCacheStuffer或SpannedCacheStuffer个性化你的弹幕样式
        final Paint paint = new Paint();


        @Override
        public void measure(BaseDanmaku danmaku, TextPaint paint) {
            danmaku.padding = 10;  // 在背景绘制模式下增加padding
            super.measure(danmaku, paint);
        }


        @Override
        public void drawBackground(BaseDanmaku danmaku, Canvas canvas, float left, float top) {
            paint.setColor(0x8125309b);  //弹幕背景颜色
            canvas.drawRect(left + 2, top + 2, left + danmaku.paintWidth - 2, top + danmaku.paintHeight - 2, paint);
        }


        @Override
        public void drawStroke(BaseDanmaku danmaku, String lineText, Canvas canvas, float left, float top, Paint paint) {
            // 禁用描边绘制
        }
    }

3、添加弹幕(注意start和during的值)
//将弹幕加入队列进行显示
   private void addDanmaku(boolean islive, long start, long during, String data) {
       BaseDanmaku danmaku = DanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
       if (danmaku == null || mDanmakuView == null) {
           return;
       }
       // for(int i=0;i<100;i++){
       // }
       danmaku.text = data;
       danmaku.padding = 5;
       danmaku.priority = 1; //0时会被过滤掉
       danmaku.isLive = islive;


       danmaku.time = mDanmakuView.getCurrentTime() + start; //时间start的值不要太小

       danmaku.duration = new Duration(during); //显示时间
//为了让弹幕能够完全显示,during不能超过DanmakuFactory.MAX_DANMAKU_DURATION,否则显示未到达屏幕边界就消失
       //danmaku.duration.setFactor((float)Math.random() * 2); //滚动速度系数,越小越快
       danmaku.textSize = 25f * (mParser.getDisplayer().getDensity() - 0.6f);
       danmaku.textColor = Color.WHITE;
       danmaku.textShadowColor = Color.WHITE; //Color.WHITE;
       // danmaku.underlineColor = Color.GREEN;
       danmaku.borderColor = 0; //边框
       mDanmakuView.addDanmaku(danmaku);
   }

注意:绘制线程当没有内容绘制时将wait休眠一段时间,导致部分弹幕显示起始点不是屏幕边界,为了让加入的弹幕能够从边界开始显示,加入弹幕前后加入以下代码
mDanmakuView.pause(); mDanmakuView.resume();

 类似资料: