基于IJKDanmakuFlameMaster的android 弹幕接入

本文详细介绍了弹幕系统的开发流程,包括导入依赖、初始化关键全局变量、加载远程图片、弹幕显示设置、属性操作以及播放器交互。通过实例演示如何实现弹幕的创建、展示和管理。

首先import 弹幕包

import master.flame.danmaku.danmaku.util.SystemClock;

import master.flame.danmaku.controller.IDanmakuView;
import master.flame.danmaku.danmaku.loader.ILoader;
import master.flame.danmaku.danmaku.loader.IllegalDataException;
import master.flame.danmaku.danmaku.loader.android.DanmakuLoaderFactory;
import master.flame.danmaku.danmaku.model.BaseDanmaku;
import master.flame.danmaku.danmaku.model.DanmakuTimer;
import master.flame.danmaku.danmaku.model.IDanmakus;
import master.flame.danmaku.danmaku.model.IDisplayer;
import master.flame.danmaku.danmaku.model.android.BaseCacheStuffer;
import master.flame.danmaku.danmaku.model.android.DanmakuContext;
import master.flame.danmaku.danmaku.model.android.Danmakus;
import master.flame.danmaku.danmaku.model.android.SpannedCacheStuffer;
import master.flame.danmaku.danmaku.parser.BaseDanmakuParser;
import master.flame.danmaku.danmaku.parser.IDataSource;
import master.flame.danmaku.danmaku.parser.android.BiliDanmukuParser;
import master.flame.danmaku.danmaku.util.IOUtils;

定义全局变量

 private IDanmakuView mDanmakuView;
 private BaseDanmakuParser mParser;
 private DanmakuContext mContext;

启动单个线程加载远程图片

private BaseCacheStuffer.Proxy mCacheStufferAdapter = new BaseCacheStuffer.Proxy() {

        private Drawable mDrawable;

        @Override
        public void prepareDrawing(final BaseDanmaku danmaku, boolean fromWorkerThread) {
            if (danmaku.text instanceof Spanned) { // 根据你的条件检查是否需要需要更新弹幕
                // FIXME 这里只是简单启个线程来加载远程url图片,请使用你自己的异步线程池,最好加上你的缓存池
                new Thread() {

                    @Override
                    public void run() {
                        String url = "http://vod.vbyte.cn/leifeng32.ico";
                        InputStream inputStream = null;
                        Drawable drawable = mDrawable;
                        if(drawable == null) {
                            try {
                                URLConnection urlConnection = new URL(url).openConnection();
                                inputStream = urlConnection.getInputStream();
                                drawable = BitmapDrawable.createFromStream(inputStream, "bitmap");
                                mDrawable = drawable;
                            } catch (MalformedURLException e) {
                                e.printStackTrace();
                            } catch (IOException e) {
                                e.printStackTrace();
                            } finally {
                                IOUtils.closeQuietly(inputStream);
                            }
                        }
                        if (drawable != null) {
                            drawable.setBounds(0, 0, 100, 100);
                            SpannableStringBuilder spannable = createSpannable(drawable);
                            danmaku.text = spannable;
                            if(mDanmakuView != null) {
                                mDanmakuView.invalidateDanmaku(danmaku, false);
                            }
                            return;
                        }
                    }
                }.start();
            }
        }

        @Override
        public void releaseResource(BaseDanmaku danmaku) {
            // TODO 重要:清理含有ImageSpan的text中的一些占用内存的资源 例如drawable
        }
    };

设置最大显示行数及是否进制重叠

HashMap<Integer, Integer> maxLinesPair = new HashMap<Integer, Integer>();
// 滚动弹幕最大显示5行
maxLinesPair.put(BaseDanmaku.TYPE_SCROLL_RL, 5); 

HashMap<Integer, Boolean> overlappingEnablePair = new HashMap<Integer, Boolean>();
overlappingEnablePair.put(BaseDanmaku.TYPE_SCROLL_RL, true);
overlappingEnablePair.put(BaseDanmaku.TYPE_FIX_TOP, true);

接下来初始化上面定义的最关键三个全局变量

mDanmakuView = (IDanmakuView) findViewById(R.id.sv_danmaku);
mContext = DanmakuContext.create();
mContext.setDanmakuStyle(IDisplayer.DANMAKU_STYLE_STROKEN,3)
     .setDuplicateMergingEnabled(false)
     .setScaleTextSize(1.2f)
     // 图文混排使用SpannedCacheStuffer
        .setCacheStuffer(new SpannedCacheStuffer(), mCacheStufferAdapter) 
        .setMaximumLines(maxLinesPair)
        .preventOverlapping(overlappingEnablePair);
          if (mDanmakuView != null) {
          //很明显,这就是我们弹幕的显示资源
            mParser = createParser(this.getResources().openRawResource(R.raw.comments));
            mDanmakuView.setCallback(new master.flame.danmaku.controller.DrawHandler.Callback() {
                @Override
                public void updateTimer(DanmakuTimer timer) {
                }

                @Override
                public void drawingFinished() {

                }

                @Override
                public void danmakuShown(BaseDanmaku danmaku) {

                }

                @Override
                public void prepared() {
                    mDanmakuView.start();
                }
            });
            mDanmakuView.setOnDanmakuClickListener(new IDanmakuView.OnDanmakuClickListener() {
                @Override
                public void onDanmakuClick(BaseDanmaku latest) {

                }

                @Override
                public void onDanmakuClick(IDanmakus danmakus) {

                }
            });
            mDanmakuView.prepare(mParser, mContext);
            mDanmakuView.showFPS(true);
            mDanmakuView.enableDanmakuDrawingCache(true);
            ((View) mDanmakuView).setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View view) {
                    mMediaController.setVisibility(View.VISIBLE);
                }
            });
        }

下面是跟随播放器的一些弹幕库的暂定、播放、释放资源的操作

    @Override
    protected void onPause() {
        super.onPause();
        if (mDanmakuView != null && mDanmakuView.isPrepared()) {
            mDanmakuView.pause();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mDanmakuView != null && mDanmakuView.isPrepared() && mDanmakuView.isPaused()) {
            mDanmakuView.resume();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mDanmakuView != null) {
            // dont forget release!
            mDanmakuView.release();
            mDanmakuView = null;
        }
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        if (mDanmakuView != null) {
            // dont forget release!
            mDanmakuView.release();
            mDanmakuView = null;
        }
    }

弹幕的一些属性操作,可用户自设置,易理解,不解释

mDanmakuView.hide();
mDanmakuView.show();
mDanmakuView.pause();
mDanmakuView.resume();

来一条纯文本弹幕测试一下

 private void addDanmaku(boolean islive) {
        BaseDanmaku danmaku = mContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
        if (danmaku == null || mDanmakuView == null) {
            return;
        }
        danmaku.text = "这就是一条测试,至于你信不信,反正我是信了";
        danmaku.padding = 5;
        // 优先级,>0为高优先级不会被过滤器过滤,会被各种过滤器过滤并隐藏显示
        danmaku.priority = 0;  
        danmaku.isLive = islive;
        danmaku.time = mDanmakuView.getCurrentTime() + 1200;
        danmaku.textSize = 25f * (mParser.getDisplayer().getDensity() - 0.6f);
        danmaku.textColor = Color.RED;
        danmaku.textShadowColor = Color.WHITE;
        danmaku.underlineColor = Color.GREEN;
        danmaku.borderColor = Color.GREEN;
        mDanmakuView.addDanmaku(danmaku);

    }

来一条图文混编的测试一下,SpannableStringBuilder
private void addDanmaKuShowTextAndImage(boolean islive) {

    BaseDanmaku danmaku = mContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
    Drawable drawable = getResources().getDrawable(R.drawable.ic_launcher);
    drawable.setBounds(0, 0, 100, 100);
    String text = "bitmap";
    SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);
    ImageSpan span = new ImageSpan(drawable);//ImageSpan.ALIGN_BOTTOM);
    spannableStringBuilder.setSpan(span, 0, text.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    spannableStringBuilder.append("我只是个图文混排的测试");
    spannableStringBuilder.setSpan(new BackgroundColorSpan(Color.parseColor("#8A2233B1")), 0, spannableStringBuilder.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
    //以上部分是与纯文本的区别,显示资源的区别

    danmaku.text = spannable;
    danmaku.padding = 5;
    danmaku.priority = 1;  // 一定会显示, 一般用于本机发送的弹幕
    danmaku.isLive = islive;
    danmaku.time = mDanmakuView.getCurrentTime() + 1200;
    danmaku.textSize = 25f * (mParser.getDisplayer().getDensity() - 0.6f);
    danmaku.textColor = Color.RED;
    danmaku.textShadowColor = 0; // 重要:如果有图文混排,最好不要设置描边(设textShadowColor=0),否则会进行两次复杂的绘制导致运行效率降低
    danmaku.underlineColor = Color.GREEN;
    mDanmakuView.addDanmaku(danmaku);
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值