bilibili / danmakuflamemaster Goto Github PK
View Code? Open in Web Editor NEWAndroid开源弹幕引擎·烈焰弹幕使 ~
Home Page: http://app.bilibili.com/
License: Apache License 2.0
Android开源弹幕引擎·烈焰弹幕使 ~
Home Page: http://app.bilibili.com/
License: Apache License 2.0
看到有几行codes关于实时弹幕。不过那个实现会影响整体的timer.
如果实时弹幕和非实时弹幕同时出现,就不行了吧。
而且貌似完全不work.
给弹幕设置duration,当一大波弹幕发出来后,有些弹幕走到半路忽然消失,不设置duration正常
会导致同屏密度出现小误差
我用Sample ,点击按钮的时候seek到一个固定的位置,会导致程序崩溃。有时一次就崩溃,有时点击多次后崩溃
12-25 10:44:42.261: I/dalvikvm-heap(686): Grow heap (frag case) to 20.435MB for 45376-byte allocation
12-25 10:44:42.292: D/dalvikvm(686): GC_FOR_ALLOC freed <1K, 13% free 18550K/21124K, paused 29ms, total 29ms
12-25 10:44:42.292: I/dalvikvm-heap(686): Grow heap (frag case) to 20.524MB for 69232-byte allocation
12-25 10:44:42.695: D/dalvikvm(686): Trying to load lib /data/app-lib/com.sample-1/libndkbitmap.so 0x42201f18
12-25 10:44:42.695: D/dalvikvm(686): Shared lib '/data/app-lib/com.sample-1/libndkbitmap.so' already loaded in same CL 0x42201f18
12-25 10:44:42.700: E/NativeBitmapFactory(686): loadedfalse
12-25 10:44:46.813: D/dalvikvm(686): Trying to load lib /data/app-lib/com.sample-1/libndkbitmap.so 0x42201f18
12-25 10:44:46.813: D/dalvikvm(686): Shared lib '/data/app-lib/com.sample-1/libndkbitmap.so' already loaded in same CL 0x42201f18
12-25 10:44:46.822: E/NativeBitmapFactory(686): loadedfalse
12-25 10:44:46.822: A/libc(686): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 756 (DFM Cache-Build)
即使一个弹幕都没有也会出现这个问题。
java.util.ConcurrentModificationException
java.util.TreeMap$MapIterator.stepForward(TreeMap.java:883)
java.util.TreeMap$BoundedMap$BoundedIterator.stepForward(TreeMap.java:1485)
java.util.TreeMap$BoundedMap$BoundedKeySet$1.next(TreeMap.java:1547)
master.flame.danmaku.danmaku.model.android.Danmakus$DanmakuIterator.a(Danmakus.java:257)
master.flame.danmaku.controller.CacheManagingDrawTask$CacheManager$CacheHandler.a(CacheManagingDrawTask.java:571)
master.flame.danmaku.controller.CacheManagingDrawTask$CacheManager$CacheHandler.handleMessage(CacheManagingDrawTask.java:423)
android.os.Handler.dispatchMessage(Handler.java:99)
android.os.Looper.loop(Looper.java:153)
android.os.HandlerThread.run(HandlerThread.java:60)
如果能支持类似用户头像或者是表情就更好啦
现在DanmakuGlobalConfig只能限制同屏弹幕数量,想固定在顶部或底部显示2-3行的弾幕,以便不影响观看体验
没有找到循环播放的方法在哪里、、、
请问这个库支持qq那种图片表情呢?
DanmakuSurfaceView无此问题, 应该是DrawHandler调整timer的更新出了问题
目前弹幕中只支持简单的文字,如果我要在弹幕中图文同时显示呢??
退出的时候没有将danmakuList清空,如果连续播放的时候,下一个视频刚好没有弹幕内容,整个view没有被destroy而仅仅是stop的话。那么前一个视频的弹幕将会出现在下一个视频上。
建议在drawTask.quit的时候,加一个danmakuList.clear();
最近随着播放器的高级弹幕工具完善,B站现在有越来越多的轨迹跟踪弹幕,比如这个 http://comment.bilibili.com/2196678.xml 之类的。不知是否可能加入新的轨迹弹幕策略。
粗略测试看到最后的数组是的M
,L
就是常见轨迹定义(参考SVG Path),整个轨迹使用的时间同原来的移动Duration。
不过可能需要比较大的改动,从简单的 beginX
,beginY
,endX
,endY
切换到一个坐标和时间序列数组。当然这样就能支持A站的移动弹幕了(A站默认就支持轨迹移动)。
如题,需要加载完毕后重新播放,或者去更新弹幕数据.
我sample程序跑起来,点击发送一条弹幕,没有任何显示,这是为啥?
用handler当系统比较忙的时候往往会跳帧。严重影响体验。
建议用Choreographer来实现
参见 http://developer.android.com/reference/android/view/Choreographer.html
12-26 10:25:46.852: E/AndroidRuntime(8092): FATAL EXCEPTION: DFM Cache-Building Thread
12-26 10:25:46.852: E/AndroidRuntime(8092): java.util.ConcurrentModificationException
12-26 10:25:46.852: E/AndroidRuntime(8092): at java.util.TreeMap$MapIterator.stepForward(TreeMap.java:883)
12-26 10:25:46.852: E/AndroidRuntime(8092): at java.util.TreeMap$BoundedMap$BoundedIterator.stepForward(TreeMap.java:1484)
12-26 10:25:46.852: E/AndroidRuntime(8092): at java.util.TreeMap$BoundedMap$BoundedKeySet$1.next(TreeMap.java:1546)
12-26 10:25:46.852: E/AndroidRuntime(8092): at master.flame.danmaku.danmaku.model.android.Danmakus$DanmakuIterator.next(Danmakus.java:257)
12-26 10:25:46.852: E/AndroidRuntime(8092): at master.flame.danmaku.controller.CacheManagingDrawTask$CacheManager$CacheHandler.prepareCaches(CacheManagingDrawTask.java:567)
12-26 10:25:46.852: E/AndroidRuntime(8092): at master.flame.danmaku.controller.CacheManagingDrawTask$CacheManager$CacheHandler.handleMessage(CacheManagingDrawTask.java:424)
12-26 10:25:46.852: E/AndroidRuntime(8092): at android.os.Handler.dispatchMessage(Handler.java:99)
12-26 10:25:46.852: E/AndroidRuntime(8092): at android.os.Looper.loop(Looper.java:137)
12-26 10:25:46.852: E/AndroidRuntime(8092): at android.os.HandlerThread.run(HandlerThread.java:60)
下面是demo中的代码
BaseDanmakuParser mParser;
mParser = createParser( this.getResources().openRawResource( R.raw.comments ) );
1、mParser.getTimer().currMillisecond这个时间是怎么来的,用来做什么的?
2、R.raw.comments这个xml是用来做什么用的,看了里面的内容,有点想是弹幕的配置结构。貌似我这里没这个文件,那怎么创建这个Parser??
3、
mDanmakuView.setCallback( new Callback()
{
@OverRide
public void updateTimer( DanmakuTimer timer )
{
}
@OverRide
public void prepared()
{
mDanmakuView.start();
}
} );
我想知道这个updateTimer有什么作用,这个方法里面是处理什么的???
4、怎么来做到跟视频播放同步显示。
报错信息如下
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4290fee0
at android.graphics.Canvas.throwIfRecycled(Canvas.java:1026)
at android.graphics.Canvas.drawBitmap(Canvas.java:1065)
at master.flame.danmaku.danmaku.model.android.AndroidDisplayer.draw(Unknown Source)
at master.flame.danmaku.danmaku.model.BaseDanmaku.draw(Unknown Source)
at master.flame.danmaku.danmaku.renderer.android.DanmakuRenderer.draw(Unknown Source)
at master.flame.danmaku.controller.DrawTask.drawDanmakus(Unknown Source)
at master.flame.danmaku.controller.DrawTask.draw(Unknown Source)
at master.flame.danmaku.controller.CacheManagingDrawTask.draw(Unknown Source)
at master.flame.danmaku.controller.DrawHandler.draw(Unknown Source)
at master.flame.danmaku.ui.widget.DanmakuSurfaceView.drawDanmakus(Unknown Source)
at master.flame.danmaku.controller.DrawHandler.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:153)
at android.os.HandlerThread.run(HandlerThread.java:60)
问题在AndroidDisplayer 200行
if (holder != null && holder.bitmap != null )->
if (holder != null && holder.bitmap != null && !holder.bitmap.isRecycled())
@ctiao 看看是不是这样改
你好,从0.1.7开始,minSdkVersion只支持到14了吗?,我从0.1.6换到0.1.7就开始报错
Error:Execution failed for task ':app:processDebugManifest'.
Manifest merger failed : uses-sdk:minSdkVersion 9 cannot be smaller than version 14 declared in library me.neavo:danmakuflamemaster:0.1.7
我在DrawHanlder的Update中加了个打印,发现Update是每15ms被调用一次,很精确。
我又在R2LDanmaku,java的getLeft中加了打印,发现它的调用时间非常不精确。有时候40ms才被调用一次。
我想getLeft没有及时更新,才是导致弹幕抖动闪烁额的根本原因。
从理论上,如果Update能够保证15ms调用一次,那么getLeft应该15ms调用一次,才能保证移动的平滑
见以下log
log中Time 16ms是在Update中打印的,16ms表示距离前一次打印的相对时间。
Time 8934, 201.963989, 41db17c8是在getLeft中打印的
8934是currentTime, 201是算出来的Left位置,41db17c8是某一条弹幕的HashCode
从log中可以看到,Update的调用时刻很准。但是常常几次update以后才调用一次getLeft。
05-04 17:43:30.770: I/DBG(3624): Time 8886, 207.755981, 41db17c8
05-04 17:43:30.770: I/DBG(3624): Time 16
05-04 17:43:30.790: I/DBG(3624): Time 16
05-04 17:43:30.790: I/DBG(3624): Time 8918, 203.894653, 41db17c8
05-04 17:43:30.800: I/DBG(3624): Time 16
05-04 17:43:30.810: I/DBG(3624): Time 8934, 201.963989, 41db17c8
05-04 17:43:30.820: I/DBG(3624): Time 18
05-04 17:43:30.840: I/DBG(3624): Time 16
05-04 17:43:30.850: I/DBG(3624): Time 8968, 197.861328, 41db17c8
05-04 17:43:30.860: I/DBG(3624): Time 18
05-04 17:43:30.870: I/DBG(3624): Time 16
05-04 17:43:30.880: I/DBG(3624): Time 9002, 193.758667, 41db17c8
05-04 17:43:30.890: I/DBG(3624): Time 16
05-04 17:43:30.900: I/DBG(3624): Time 16
05-04 17:43:30.920: I/DBG(3624): Time 17
05-04 17:43:30.920: I/DBG(3624): Time 9051, 187.845947, 41db17c8
05-04 17:43:30.940: I/DBG(3624): Time 15
05-04 17:43:30.950: I/DBG(3624): Time 9066, 186.036011, 41db17c8
05-04 17:43:30.950: I/DBG(3624): Time 19
05-04 17:43:30.970: I/DBG(3624): Time 15
05-04 17:43:30.990: I/DBG(3624): Time 18
05-04 17:43:30.990: I/DBG(3624): Time 9118, 179.761353, 41db17c8
05-04 17:43:31.000: I/DBG(3624): Time 15
05-04 17:43:31.020: I/DBG(3624): Time 16
05-04 17:43:31.040: I/DBG(3624): Time 16
05-04 17:43:31.040: I/DBG(3624): Time 9165, 174.089966, 41db17c8
05-04 17:43:31.060: I/DBG(3624): Time 19
05-04 17:43:31.060: I/DBG(3624): Time 9184, 171.797363, 41db17c8
05-04 17:43:31.080: I/DBG(3624): Time 19
05-04 17:43:31.090: I/DBG(3624): Time 19
05-04 17:43:31.100: I/DBG(3624): Time 9222, 167.212036, 41db17c8
05-04 17:43:31.110: I/DBG(3624): Time 16
05-04 17:43:31.120: I/DBG(3624): Time 9238, 165.281372, 41db17c8
05-04 17:43:31.130: I/DBG(3624): Time 20
05-04 17:43:31.140: I/DBG(3624): Time 17
05-04 17:43:31.160: I/DBG(3624): Time 9275, 160.816650, 41db17c8
05-04 17:43:31.160: I/DBG(3624): Time 16
05-04 17:43:31.180: I/DBG(3624): Time 16
05-04 17:43:31.190: I/DBG(3624): Time 9307, 156.955322, 41db17c8
05-04 17:43:31.190: I/DBG(3624): Time 15
05-04 17:43:31.210: I/DBG(3624): Time 16
05-04 17:43:31.220: I/DBG(3624): Time 9338, 153.214600, 41db17c8
05-04 17:43:31.220: I/DBG(3624): Time 16
05-04 17:43:31.240: I/DBG(3624): Time 16
05-04 17:43:31.250: I/DBG(3624): Time 9370, 149.353271, 41db17c8
05-04 17:43:31.260: I/DBG(3624): Time 16
05-04 17:43:31.270: I/DBG(3624): Time 16
1.预缓存采取更加惰性的加载机制
2.增加即时缓存机制(类似现在的实时插入弹幕时候采取的方式)
以减少某些中低端机型抖动的现象
rt
It should be related to threading...
1.
06-23 19:47:02.524 F/libc ( 6103): Fatal signal 11 (SIGSEGV), thread 9371 (Cache Building )
2.
pid: 7132, tid: 7211 >>> <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
...
#00 pc 00000000
#1 pc 0007dcb4 /system/lib/libskia.so (ZN8SkCanvas8drawTextEPKvjffRK7SkPaint)
3.
pid: 1282, tid: 21964, name: Cache Building >>> <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
backtrace:
#00 pc 00000000
#1 pc 00061c80 /system/lib/libskia.so (AutoDrawLooper::next(SkDrawFilter::Type)+96)
#2 pc 00066230 /system/lib/libskia.so (SkCanvas::drawText(void const, unsigned int, float, float, SkPaint const&)+152)
#3 pc 0006bccf /system/lib/libandroid_runtime.so
#4 pc 0006bdeb /system/lib/libandroid_runtime.so
#5 pc 0001fb70 /system/lib/libdvm.so (dvmPlatformInvoke+112)
#6 pc 0004e8b9 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const_, JValue_, Method const_, Thread_)+360)
#7 pc 00029020 /system/lib/libdvm.so
#8 pc 0002d7e8 /system/lib/libdvm.so (dvmInterpret(Thread_, Method const_, JValue_)+180)
#9 pc 0005fed5 /system/lib/libdvm.so (dvmCallMethodV(Thread_, Method const_, Object_, bool, JValue_, std::va_list)+272)
#10 pc 0005feff /system/lib/libdvm.so (dvmCallMethod(Thread, Method const, Object_, JValue_, ...)+20)
#11 pc 00055327 /system/lib/libdvm.so
#12 pc 00012e70 /system/lib/libc.so (__thread_entry+48)
#13 pc 000125c8 /system/lib/libc.so (pthread_create+172)
4.
pid: 12134, tid: 13706 >>> <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
#00 pc 00000000
#1 pc 00074164 /system/lib/libskia.so (_ZN8SkCanvas8drawTextEPKvjffRK7SkPaint)
#2 pc 0006e244 /system/lib/libandroid_runtime.so
#3 pc 0006e3c2 /system/lib/libandroid_runtime.so
#4 pc 0001dab0 /system/lib/libdvm.so (dvmPlatformInvoke)
#5 pc 000586aa /system/lib/libdvm.so (_Z16dvmCallJNIMethodPKjP6JValuePK6MethodP6Thread)
5.
06-23 23:51:04.391 F/libc ( 9806): Fatal signal 11 (SIGSEGV), thread 5796 (DFM Drawing thr)
01-13 16:55:13.663: W/System.err(27536): java.lang.IllegalArgumentException: master.flame.danmaku.danmaku.model.R2LDanmaku@4364e440 not in range [master.flame.danmaku.danmaku.model.Danmaku@43608568..master.flame.danmaku.danmaku.model.Danmaku@436085e0)
at master.flame.danmaku.controller.CacheManagingDrawTask$CacheManager$CacheHandler.handleMessage(CacheManagingDrawTask.java:440)
在一些cpu比较慢的设备上,发送较长的弹幕(速度较快),会出现弹幕末尾的字符没有擦除干净。
DanmakuFilters/DanmakuFactory/DanmakuGlobalConfig
我在R2LDanmaku类的getAccurateLeft方法中打印 currTime 参数日志。
01-28 18:23:11.070: E/danmubbc(13522): currTime = 11589 time =6079 displayer.getWidth() = 1920 elapsedTime = 5510 duration.value = 5630 mStepX=0.37531084
01-28 18:23:11.071: E/danmubbc(13522): 2text = 陈佩斯 left = -147.96265
01-28 18:23:11.096: E/danmubbc(13522): 1text = 陈佩斯 left = -147.96265
01-28 18:23:11.097: E/danmubbc(13522): currTime = 11642 time =6079 displayer.getWidth() = 1920 elapsedTime = 5563 duration.value = 5630 mStepX=0.37531084
01-28 18:23:11.097: E/danmubbc(13522): 2text = 陈佩斯 left = -167.85425
01-28 18:23:11.103: E/danmubbc(13522): 1text = 陈佩斯 left = -167.85425
01-28 18:23:11.103: E/danmubbc(13522): currTime = 11695 time =6079 displayer.getWidth() = 1920 elapsedTime = 5616 duration.value = 5630 mStepX=0.37531084
01-28 18:23:11.103: E/danmubbc(13522): 2text = 陈佩斯 left = -187.7456
01-28 18:23:11.139: E/danmubbc(13522): 1text = 陈佩斯 left = -187.7456
01-28 18:23:11.139: E/danmubbc(13522): 2text = 陈佩斯 left = -187.7456
01-28 18:23:11.162: E/danmubbc(13522): 1text = 陈佩斯 left = -187.7456
01-28 18:23:11.163: E/danmubbc(13522): currTime = 9856time =6079 displayer.getWidth() = 1920 elapsedTime = 3777 duration.value = 5630 mStepX=0.37531084
01-28 18:23:11.163: E/danmubbc(13522): 2text = 陈佩斯 left = 502.45093
01-28 18:23:11.171: E/danmubbc(13522): 1text = 陈佩斯 left = 502.45093
正常情况下是currTime不断的变大,但是有时会出现currTime突然变小,然后在慢慢变大的情况。
导致的现象就是,弹幕从右到左走完后,突然又从中间显示,再向左走的情况。
currTime 的值来自mTimer.currMillisecond。所以我想知道currMillisecond是根据什么变化的,在代码的什么位置变化?
可参考并测试android的Spannable支持
现在快速绘制模式会导致弹幕设置改变和seek之后描边丢失问题
增加opengl绘制方式
增加扩展android.view.View的DanmakuView
跳转进度或者重新开始底部和顶部固定弹幕位置会出现问题
DanmakuSurfaceView 跟我自己做的播放器的SurfaceView 有冲突 。
方案:
均匀弹幕步长,使看来不会抖动,但是对于绘制效率不够的情况下 不能保证弹幕在固定时间内跑出屏幕, 参考AOSP的Scroller源码或者直接使用Scroller
我之前用的SurfaceView做的弹幕,但是CPU占用率一直比较高。大概在20%,个别峰值情况会接近30%。
之后profile了一下,发现CPU主要耗费在LockCanvas和PostCanvas上。同时由于SufaceView的Canvas是没有硬件加速的,所以绘制也会比较慢。
同时我发现TextureView的Canvas也是没有硬件加速的。所以用TextureView对于绘制速度是没有任何帮助的。
为了解决这个问题,我尝试把SurfaceView改成View。然后在OnDraw中绘制。程序整体结构不变,只是在DrawHandler中调用的drawDanmakus的内容改成postInvalidate();
@OverRide
public long drawDanmakus() {
this.postInvalidate();
return mDrawTime;
}
然后真正的绘制工作放在OnDraw中。CPU占用率基本维持在15%-17%峰值没有超过20%
然后Profile后发现现在CPU主要耗费在DanmakuRender.draw中遍历对象的操作上。
相对改动之前。CPU占用率改善还是比较明显的。
其次,我觉得,如果当前画面上没有弹幕时,此时CPU占用率应该还是可以进一步优化,因为我发现没有弹幕的时候,依然在不停的做clearCanvas的操作。
java.lang.IllegalArgumentException
at android.view.Surface.nativeUnlockCanvasAndPost(Surface.java)
at android.view.Surface.unlockCanvasAndPost(Surface.java:255)
at android.view.SurfaceView$4.unlockCanvasAndPost(SurfaceView.java:844)
at master.flame.danmaku.ui.widget.DanmakuSurfaceView.drawDanmakus()
at master.flame.danmaku.controller.DrawHandler.handleMessage()
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:61)
希望作者在百忙中抽出点时候,回答下我的问题,十分感谢。
1.弹幕透明度
2.弹幕字号大小
3.同屏弹幕密度(同屏最大数量?)
4.按弹幕类型可选显示/隐藏
5.是否描边/阴影大小
6.字体设置?
7.滚动速率调整?
8.合并重复弹幕
9.缓存池大小设置
10.支持屏蔽规则?
CacaheManagingDrawTask:
查找过期的缓存中符合条件的缓存 ( 长宽值大于等于一定范围并且没有reference的缓存
擦除后进行复用
我在fragment中使用弹幕,但是当我销毁fragment后发现弹幕数据的jsonArray并没有被回收掉,导致弹幕数据对象依旧占用内存,即使退出应用也是如此,所以我在JsonSource中 release时将mJsonArray置为null,经测试,发现已经可以正常回收,想请教下这样会有什么问题吗,感谢。
JsonSource:
@OverRide
public void release() {
IOUtils.closeQuietly(mInput);
mInput = null;
//回收mJSONArray
mJSONArray = null;
}
堆栈
java.lang.NullPointerException
at master.flame.danmaku.ui.widget.DanmakuSurfaceView.isShown(Unknown Source)
at master.flame.danmaku.ui.widget.DanmakuSurfaceView.drawDanmakus(Unknown Source)
at master.flame.danmaku.controller.DrawHandler.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)
这个isShown就几句话
public boolean isShown() {
if (handler == null || !isViewReady()) {
return false;
}
return handler.getVisibility();
}
代码中只有stopDraw里面会执行handler==null,stopDraw是在UI线程里面调用的,isShown是在mDrawThread里面调用的
@ctiao
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.