Esempio n. 1
0
 @Override
 public void removeAllDanmakus() {
   if (danmakuList == null || danmakuList.isEmpty()) return;
   synchronized (danmakuList) {
     danmakuList.clear();
   }
 }
 private static void updateSpecialDanmakusDate(float scaleX, float scaleY) {
   IDanmakus list = sSpecialDanmakus;
   IDanmakuIterator it = list.iterator();
   while (it.hasNext()) {
     SpecialDanmaku speicalDanmaku = (SpecialDanmaku) it.next();
     fillTranslationData(
         speicalDanmaku,
         speicalDanmaku.beginX,
         speicalDanmaku.beginY,
         speicalDanmaku.endX,
         speicalDanmaku.endY,
         speicalDanmaku.translationDuration,
         speicalDanmaku.translationStartDelay,
         scaleX,
         scaleY);
     LinePath[] linePaths = speicalDanmaku.linePaths;
     if (linePaths != null && linePaths.length > 0) {
       int length = linePaths.length;
       float[][] points = new float[length + 1][2];
       for (int j = 0; j < length; j++) {
         points[j] = linePaths[j].getBeginPoint();
         points[j + 1] = linePaths[j].getEndPoint();
       }
       fillLinePathData(speicalDanmaku, points, scaleX, scaleY);
     }
   }
 }
Esempio n. 3
0
 @Override
 public void removeAllLiveDanmakus() {
   if (danmakuList == null || danmakuList.isEmpty()) return;
   synchronized (danmakuList) {
     IDanmakuIterator it = danmakuList.iterator();
     while (it.hasNext()) {
       if (it.next().isLive) {
         it.remove();
       }
     }
   }
 }
Esempio n. 4
0
 @Override
 public void addDanmaku(BaseDanmaku item) {
   if (danmakuList == null) return;
   synchronized (danmakuList) {
     if (item.isLive) {
       removeUnusedLiveDanmakusIn(5);
     }
     item.setTimer(mTimer);
     item.index = danmakuList.size();
     danmakuList.addItem(item);
   }
 }
 @Override
 public synchronized void removeAllLiveDanmakus() {
   if (danmakus == null || danmakus.isEmpty()) return;
   synchronized (danmakus) {
     IDanmakuIterator it = danmakus.iterator();
     while (it.hasNext()) {
       BaseDanmaku danmaku = it.next();
       if (danmaku.isLive) {
         it.remove();
         onDanmakuRemoved(danmaku);
       }
     }
   }
 }
Esempio n. 6
0
 protected void removeUnusedLiveDanmakusIn(int msec) {
   if (danmakuList == null || danmakuList.isEmpty()) return;
   long startTime = System.currentTimeMillis();
   IDanmakuIterator it = danmakuList.iterator();
   while (it.hasNext()) {
     BaseDanmaku danmaku = it.next();
     if (danmaku.isLive && danmaku.isTimeOut()) {
       it.remove();
     }
     if (System.currentTimeMillis() - startTime > msec) {
       break;
     }
   }
 }
 protected synchronized void removeUnusedLiveDanmakusIn(int msec) {
   if (danmakuList == null || danmakuList.isEmpty()) return;
   long startTime = System.currentTimeMillis();
   IDanmakuIterator it = danmakuList.iterator();
   while (it.hasNext()) {
     BaseDanmaku danmaku = it.next();
     boolean isTimeout = danmaku.isTimeOut();
     if (isTimeout && danmaku.isLive) {
       it.remove();
       onDanmakuRemoved(danmaku);
     }
     if (!isTimeout || System.currentTimeMillis() - startTime > msec) {
       break;
     }
   }
 }
Esempio n. 8
0
 protected RenderingState drawDanmakus(AbsDisplayer<?> disp, DanmakuTimer timer) {
   if (danmakuList != null) {
     Canvas canvas = (Canvas) disp.getExtraData();
     if (clearFlag > 0) {
       DrawHelper.clearCanvas(canvas);
       clearFlag--;
     } else {
       float[] refreshRect = mRenderer.getRefreshArea().mRefreshRect;
       mRectCache.push(refreshRect);
       float[] rect = mRectCache.getRect();
       DrawHelper.clearCanvas(
           canvas,
           Math.max(0, rect[0]),
           Math.max(0, rect[1]),
           Math.min(disp.getWidth(), rect[2]),
           Math.min(disp.getHeight(), rect[3]));
     }
     long currMills = timer.currMillisecond;
     danmakus = danmakuList.sub(currMills - DanmakuFactory.MAX_DANMAKU_DURATION - 100, currMills);
     if (danmakus != null) {
       return mRenderer.draw(mDisp, danmakus, mStartRenderTime);
     }
   }
   return null;
 }
 protected RenderingState drawDanmakus(AbsDisplayer<?> disp, DanmakuTimer timer) {
   if (clearRetainerFlag) {
     DanmakusRetainer.clear();
     clearRetainerFlag = false;
   }
   if (danmakuList != null) {
     Canvas canvas = (Canvas) disp.getExtraData();
     DrawHelper.clearCanvas(canvas);
     if (mIsHidden) {
       return mRenderingState;
     }
     long beginMills = timer.currMillisecond - DanmakuFactory.MAX_DANMAKU_DURATION - 100;
     long endMills = timer.currMillisecond + DanmakuFactory.MAX_DANMAKU_DURATION;
     if (mLastBeginMills > beginMills || timer.currMillisecond > mLastEndMills) {
       IDanmakus subDanmakus = danmakuList.sub(beginMills, endMills);
       if (subDanmakus != null) {
         danmakus = subDanmakus;
       } else {
         danmakus.clear();
       }
       mLastBeginMills = beginMills;
       mLastEndMills = endMills;
     } else {
       beginMills = mLastBeginMills;
       endMills = mLastEndMills;
     }
     if (danmakus != null && !danmakus.isEmpty()) {
       RenderingState renderingState =
           mRenderingState = mRenderer.draw(mDisp, danmakus, mStartRenderTime);
       if (renderingState.nothingRendered) {
         if (renderingState.beginTime == RenderingState.UNKNOWN_TIME) {
           renderingState.beginTime = beginMills;
         }
         if (renderingState.endTime == RenderingState.UNKNOWN_TIME) {
           renderingState.endTime = endMills;
         }
       }
       return renderingState;
     } else {
       mRenderingState.nothingRendered = true;
       mRenderingState.beginTime = beginMills;
       mRenderingState.endTime = endMills;
       return mRenderingState;
     }
   }
   return null;
 }
  /**
   * 创建弹幕数据请尽量使用此方法,参考BiliDanmakuParser或AcfunDanmakuParser
   *
   * @param type 弹幕类型
   * @param viewportWidth danmakuview宽度,会影响滚动弹幕的存活时间(duration)
   * @param viewportHeight danmakuview高度
   * @param viewportScale 缩放比例,会影响滚动弹幕的存活时间(duration)
   * @return
   */
  public static BaseDanmaku createDanmaku(
      int type, float viewportWidth, float viewportHeight, float viewportScale) {
    boolean sizeChanged = false;
    if (CURRENT_DISP_WIDTH != (int) viewportWidth || CURRENT_DISP_HEIGHT != (int) viewportHeight) {
      sizeChanged = true;
      REAL_DANMAKU_DURATION =
          (long) (COMMON_DANMAKU_DURATION * (viewportScale * viewportWidth / BILI_PLAYER_WIDTH));
      REAL_DANMAKU_DURATION = Math.min(MAX_DANMAKU_DURATION_HIGH_DENSITY, REAL_DANMAKU_DURATION);
      REAL_DANMAKU_DURATION = Math.max(MIN_DANMAKU_DURATION, REAL_DANMAKU_DURATION);
    }

    if (MAX_Duration_Scroll_Danmaku == null) {
      MAX_Duration_Scroll_Danmaku = new Duration(REAL_DANMAKU_DURATION);
      MAX_Duration_Scroll_Danmaku.setFactor(DanmakuGlobalConfig.DEFAULT.scrollSpeedFactor);
    } else if (sizeChanged) {
      MAX_Duration_Scroll_Danmaku.setValue(REAL_DANMAKU_DURATION);
    }

    if (MAX_Duration_Fix_Danmaku == null) {
      MAX_Duration_Fix_Danmaku = new Duration(COMMON_DANMAKU_DURATION);
    }

    if (sizeChanged && viewportWidth > 0) {
      updateMaxDanmakuDuration();
      float scaleX = 1f;
      float scaleY = 1f;
      if (CURRENT_DISP_WIDTH > 0 && CURRENT_DISP_HEIGHT > 0) {
        scaleX = viewportWidth / (float) CURRENT_DISP_WIDTH;
        scaleY = viewportHeight / (float) CURRENT_DISP_HEIGHT;
      }
      CURRENT_DISP_WIDTH = (int) viewportWidth;
      CURRENT_DISP_HEIGHT = (int) viewportHeight;
      if (viewportHeight > 0) {
        updateSpecialDanmakusDate(scaleX, scaleY);
      }
    }

    BaseDanmaku instance = null;
    switch (type) {
      case 1: // 从右往左滚动
        instance = new R2LDanmaku(MAX_Duration_Scroll_Danmaku);
        break;
      case 4: // 底端固定
        instance = new FBDanmaku(MAX_Duration_Fix_Danmaku);
        break;
      case 5: // 顶端固定
        instance = new FTDanmaku(MAX_Duration_Fix_Danmaku);
        break;
      case 6: // 从左往右滚动
        instance = new L2RDanmaku(MAX_Duration_Scroll_Danmaku);
        break;
      case 7: // 特殊弹幕
        instance = new SpecialDanmaku();
        sSpecialDanmakus.addItem(instance);
        break;
    }
    return instance;
  }
 public static void resetDurationsData() {
   sLastDisp = null;
   CURRENT_DISP_WIDTH = CURRENT_DISP_HEIGHT = 0;
   sSpecialDanmakus.clear();
   MAX_Duration_Scroll_Danmaku = null;
   MAX_Duration_Fix_Danmaku = null;
   MAX_Duration_Special_Danmaku = null;
   MAX_DANMAKU_DURATION = MIN_DANMAKU_DURATION;
 }
Esempio n. 12
0
 @Override
 public synchronized void addDanmaku(BaseDanmaku item) {
   if (danmakuList == null) return;
   boolean added = false;
   if (item.isLive) {
     removeUnusedLiveDanmakusIn(10);
   }
   item.index = danmakuList.size();
   if (mLastBeginMills <= item.time && item.time <= mLastEndMills) {
     synchronized (danmakus) {
       added = danmakus.addItem(item);
     }
   } else if (item.isLive) {
     mLastBeginMills = mLastEndMills = 0;
   }
   synchronized (danmakuList) {
     added = danmakuList.addItem(item);
   }
   if (added && mTaskListener != null) {
     mTaskListener.onDanmakuAdd(item);
   }
 }
Esempio n. 13
0
 @Override
 public void reset() {
   if (danmakus != null) danmakus.clear();
   if (mRenderer != null) mRenderer.clear();
 }
      private long prepareCaches(boolean repositioned) {
        long curr = mCacheTimer.currMillisecond;
        long end = curr + mContext.mDanmakuFactory.MAX_DANMAKU_DURATION * mScreenSize;
        if (end < mTimer.currMillisecond) {
          return 0;
        }
        long startTime = SystemClock.uptimeMillis();
        IDanmakus danmakus = null;
        int tryCount = 0;
        boolean hasException = false;
        do {
          try {
            danmakus = danmakuList.subnew(curr, end);
          } catch (Exception e) {
            hasException = true;
            SystemClock.sleep(10);
          }
        } while (++tryCount < 3 && danmakus == null && hasException);
        if (danmakus == null) {
          mCacheTimer.update(end);
          return 0;
        }
        BaseDanmaku first = danmakus.first();
        BaseDanmaku last = danmakus.last();
        if (first == null || last == null) {
          mCacheTimer.update(end);
          return 0;
        }
        long deltaTime = first.time - mTimer.currMillisecond;
        long sleepTime = 30 + 10 * deltaTime / mContext.mDanmakuFactory.MAX_DANMAKU_DURATION;
        sleepTime = Math.min(100, sleepTime);
        if (repositioned) {
          sleepTime = 0;
        }

        IDanmakuIterator itr = danmakus.iterator();
        BaseDanmaku item = null;
        long consumingTime = 0;
        int orderInScreen = 0;
        int currScreenIndex = 0;
        int sizeInScreen = danmakus.size();
        //                String message = "";
        while (!mPause && !mCancelFlag) {
          boolean hasNext = itr.hasNext();
          if (!hasNext) {
            //                        message = "break at not hasNext";
            break;
          }
          item = itr.next();

          if (last.time < mTimer.currMillisecond) {
            //                        message = "break at last.time < mTimer.currMillisecond";
            break;
          }

          if (item.hasDrawingCache()) {
            continue;
          }

          if (repositioned == false && (item.isTimeOut() || !item.isOutside())) {
            continue;
          }

          if (!item.hasPassedFilter()) {
            mContext.mDanmakuFilters.filter(
                item, orderInScreen, sizeInScreen, null, true, mContext);
          }

          // Log.e("prepareCache", currScreenIndex+","+orderInScreen+"," + item.time+"skip:"+skip);
          if (item.priority == 0 && item.isFiltered()) {
            continue;
          }

          if (item.getType() == BaseDanmaku.TYPE_SCROLL_RL) {
            // 同屏弹幕密度只对滚动弹幕有效
            int screenIndex =
                (int) ((item.time - curr) / mContext.mDanmakuFactory.MAX_DANMAKU_DURATION);
            if (currScreenIndex == screenIndex) orderInScreen++;
            else {
              orderInScreen = 0;
              currScreenIndex = screenIndex;
            }
          }

          if (!repositioned) {
            try {
              synchronized (mDrawingNotify) {
                mDrawingNotify.wait(sleepTime);
              }
            } catch (InterruptedException e) {
              e.printStackTrace();
              break;
            }
          }

          // build cache
          if (buildCache(item, false) == RESULT_FAILED) {
            // message = "break at build failed";
            break;
          }

          if (!repositioned) {
            consumingTime = SystemClock.uptimeMillis() - startTime;
            if (consumingTime >= DanmakuFactory.COMMON_DANMAKU_DURATION * mScreenSize) {
              //                            message = "break at consumingTime out:" + consumingTime;
              break;
            }
          }
        }
        consumingTime = SystemClock.uptimeMillis() - startTime;
        if (item != null) {
          mCacheTimer.update(item.time);
          // Log.i("cache","stop at :"+item.time+","+count+",size:"+danmakus.size()+","+message);
        } else {
          mCacheTimer.update(end);
        }
        return consumingTime;
      }