Support danmu - part 5

pull/142/head
FongMi 3 years ago
parent 8ef612ea74
commit 9e85d19671
  1. 6
      app/src/main/java/com/fongmi/android/tv/player/danmu/Parser.java
  2. 23
      app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java
  3. 2
      danmaku/src/main/java/master/flame/danmaku/controller/CacheManagingDrawTask.java
  4. 16
      danmaku/src/main/java/master/flame/danmaku/controller/DrawHandler.java
  5. 2
      danmaku/src/main/java/master/flame/danmaku/danmaku/model/android/DanmakuContext.java
  6. 24
      danmaku/src/main/java/master/flame/danmaku/danmaku/parser/BaseDanmakuParser.java
  7. 12
      danmaku/src/main/java/master/flame/danmaku/ui/widget/DanmakuView.java
  8. 103
      danmaku/src/main/java/tv/cjump/jni/NativeBitmapFactory.java
  9. BIN
      danmaku/src/main/jniLibs/arm64-v8a/libndkbitmap.so
  10. BIN
      danmaku/src/main/jniLibs/armeabi-v7a/libndkbitmap.so

@ -49,15 +49,15 @@ public class Parser extends BaseDanmakuParser {
@Override
public BaseDanmakuParser setDisplay(IDisplay display) {
super.setDisplay(display);
scaleX = mDispWidth / DanmakuFactory.BILI_PLAYER_WIDTH;
scaleY = mDispHeight / DanmakuFactory.BILI_PLAYER_HEIGHT;
scaleX = mDisplayWidth / DanmakuFactory.BILI_PLAYER_WIDTH;
scaleY = mDisplayHeight / DanmakuFactory.BILI_PLAYER_HEIGHT;
return this;
}
private void setParam(String[] values) {
int type = Integer.parseInt(values[1]);
long time = (long) (Float.parseFloat(values[0]) * 1000);
float size = Float.parseFloat(values[2]) * (mDispDensity - 0.6f);
float size = Float.parseFloat(values[2]) * (mDisplayDensity - 0.6f);
int color = (int) ((0x00000000ff000000L | Long.parseLong(values[3])) & 0x00000000ffffffffL);
item = mContext.mDanmakuFactory.createDanmaku(type, mContext);
item.setTime(time);

@ -61,6 +61,7 @@ import com.fongmi.android.tv.model.SiteViewModel;
import com.fongmi.android.tv.player.ExoUtil;
import com.fongmi.android.tv.player.Players;
import com.fongmi.android.tv.player.Source;
import com.fongmi.android.tv.player.danmu.Parser;
import com.fongmi.android.tv.service.PlaybackService;
import com.fongmi.android.tv.ui.adapter.EpisodeAdapter;
import com.fongmi.android.tv.ui.adapter.FlagAdapter;
@ -101,7 +102,8 @@ import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import master.flame.danmaku.danmaku.model.IDanmakus;
import master.flame.danmaku.danmaku.model.IDisplay;
import master.flame.danmaku.danmaku.model.android.DanmakuContext;
import tv.danmaku.ijk.media.player.ui.IjkVideoView;
public class VideoActivity extends BaseActivity implements Clock.Callback, CustomKeyDownVod.Listener, CastDialog.Listener, TrackDialog.Listener, ControlDialog.Listener, FlagAdapter.OnClickListener, EpisodeAdapter.OnClickListener, QualityAdapter.OnClickListener, QuickAdapter.OnClickListener, ParseAdapter.OnClickListener, SubtitleCallback {
@ -111,6 +113,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
private Observer<Result> mObserveDetail;
private Observer<Result> mObservePlayer;
private Observer<Result> mObserveSearch;
private DanmakuContext mDanmakuContext;
private EpisodeAdapter mEpisodeAdapter;
private QualityAdapter mQualityAdapter;
private ControlDialog mControlDialog;
@ -262,7 +265,8 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (TextUtils.isEmpty(intent.getStringExtra("id"))) return;
String id = intent.getStringExtra("id");
if (TextUtils.isEmpty(id) || id.equals(getId())) return;
mBinding.swipeLayout.setRefreshing(true);
getIntent().putExtras(intent);
stopSearch();
@ -274,6 +278,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
protected void initView(Bundle savedInstanceState) {
mKeyDown = CustomKeyDownVod.create(this, mBinding.video);
mFrameParams = mBinding.video.getLayoutParams();
mDanmakuContext = DanmakuContext.create();
mBinding.progressLayout.showProgress();
mBinding.swipeLayout.setEnabled(false);
mPlayers = new Players().init(this);
@ -292,6 +297,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
setForeground(true);
setRecyclerView();
setVideoView();
setDanmuView();
setViewModel();
showProgress();
checkId();
@ -383,6 +389,11 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
setSubtitle(14);
}
private void setDanmuView() {
mPlayers.setDanmuView(mBinding.danmu);
mDanmakuContext.setDanmakuStyle(IDisplay.DANMAKU_STYLE_STROKEN, 3).setDanmakuMargin(ResUtil.dp2px(24));
}
@Override
public void setSubtitle(int size) {
getExo().getSubtitleView().setFixedTextSize(Dimension.SP, size);
@ -509,11 +520,13 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
mBinding.quality.setVisibility(result.getUrl().isOnly() ? View.GONE : View.VISIBLE);
mBinding.swipeLayout.setRefreshing(false);
mQualityAdapter.addAll(result);
loadDanmu(result.getDanmakus());
checkDanmu(result.getDanmaku());
}
private void loadDanmu(IDanmakus danmakus) {
private void checkDanmu(String danmu) {
mBinding.danmu.release();
mBinding.danmu.setVisibility(danmu.isEmpty() ? View.GONE : View.VISIBLE);
if (danmu.length() > 0) mBinding.danmu.prepare(new Parser(danmu), mDanmakuContext);
}
@Override

@ -51,7 +51,6 @@ public class CacheManagingDrawTask extends DrawTask {
public CacheManagingDrawTask(DanmakuTimer timer, DanmakuContext config, TaskListener taskListener) {
super(timer, config, taskListener);
NativeBitmapFactory.loadLibs();
mMaxCacheSize = (int) Math.max(1024 * 1024 * 4, Runtime.getRuntime().maxMemory() * config.cachingPolicy.maxCachePoolSizeFactorPercentage);
mCacheManager = new CacheManager(mMaxCacheSize, MAX_CACHE_SCREEN_SIZE);
mRenderer.setCacheManager(mCacheManager);
@ -150,7 +149,6 @@ public class CacheManagingDrawTask extends DrawTask {
mCacheManager.end();
mCacheManager = null;
}
NativeBitmapFactory.releaseLibs();
}
@Override

@ -409,14 +409,14 @@ public class DrawHandler extends Handler {
long time = startMS - mTimeBase;
if (mNonBlockModeEnable) {
if (mCallback != null) {
mCallback.updateTimer(timer);
//mCallback.updateTimer(timer);
d = timer.lastInterval();
}
} else if (!mDanmakusVisible || mRenderingState.nothingRendered || mInWaitingState) {
timer.update(time);
mRemainingTime = 0;
if (mCallback != null) {
mCallback.updateTimer(timer);
//mCallback.updateTimer(timer);
}
} else {
long gapTime = time - timer.currMillisecond;
@ -438,7 +438,7 @@ public class DrawHandler extends Handler {
mRemainingTime = gapTime;
timer.add(d);
if (mCallback != null) {
mCallback.updateTimer(timer);
//mCallback.updateTimer(timer);
}
}
mInSyncAction = false;
@ -483,12 +483,12 @@ public class DrawHandler extends Handler {
@Override
public void onDanmakuShown(BaseDanmaku danmaku) {
if (mCallback != null) mCallback.danmakuShown(danmaku);
//if (mCallback != null) mCallback.danmakuShown(danmaku);
}
@Override
public void onDanmakusDrawingFinished() {
if (mCallback != null) mCallback.drawingFinished();
//if (mCallback != null) mCallback.drawingFinished();
}
@Override
@ -752,12 +752,6 @@ public class DrawHandler extends Handler {
public interface Callback {
void prepared();
void updateTimer(DanmakuTimer timer);
void danmakuShown(BaseDanmaku danmaku);
void drawingFinished();
}
private class FrameCallback implements Choreographer.FrameCallback {

@ -45,7 +45,7 @@ public class DanmakuContext implements Cloneable {
List<String> mUserHashBlackList = new ArrayList<>();
private List<WeakReference<ConfigChangedCallback>> mCallbackList;
private boolean mBlockGuestDanmaku = false;
private boolean mDuplicateMergingEnable = false;
private boolean mDuplicateMergingEnable = true;
private boolean mIsAlignBottom = false;
private BaseCacheStuffer mCacheStuffer;
private boolean mIsMaxLinesLimited;

@ -23,14 +23,15 @@ import master.flame.danmaku.danmaku.model.android.DanmakuContext;
public abstract class BaseDanmakuParser {
protected DanmakuTimer mTimer;
protected int mDispWidth;
protected int mDispHeight;
protected float mDispDensity;
protected float mScaledDensity;
protected IDisplay mDisp;
protected DanmakuContext mContext;
protected DanmakuTimer mTimer;
private IDanmakus mDanmakus;
private IDisplay mDisp;
protected float mDisplayDensity;
protected float mScaledDensity;
protected int mDisplayHeight;
protected int mDisplayWidth;
public IDisplay getDisplay() {
return mDisp;
@ -38,21 +39,20 @@ public abstract class BaseDanmakuParser {
public BaseDanmakuParser setDisplay(IDisplay disp) {
mDisp = disp;
mDispWidth = disp.getWidth();
mDispHeight = disp.getHeight();
mDispDensity = disp.getDensity();
mDisplayWidth = disp.getWidth();
mDisplayHeight = disp.getHeight();
mDisplayDensity = disp.getDensity();
mScaledDensity = disp.getScaledDensity();
mContext.mDanmakuFactory.updateViewportState(mDispWidth, mDispHeight, getViewportSizeFactor());
mContext.mDanmakuFactory.updateViewportState(mDisplayWidth, mDisplayHeight, getViewportSizeFactor());
mContext.mDanmakuFactory.updateMaxDanmakuDuration();
return this;
}
/**
* decide the speed of scroll-danmakus
*
*/
protected float getViewportSizeFactor() {
return 1 / (mDispDensity - 0.6f);
return 1 / (mDisplayDensity - 0.6f);
}
public DanmakuTimer getTimer() {

@ -47,13 +47,14 @@ public class DanmakuView extends View implements IDanmakuView, IDanmakuViewContr
private static final int MAX_RECORD_SIZE = 50;
private static final int ONE_SECOND = 1000;
private Callback mCallback;
private Object mDrawMonitor;
private OnDanmakuClickListener mOnDanmakuClickListener;
private DanmakuTouchHelper mTouchHelper;
private HandlerThread mHandlerThread;
private LinkedList<Long> mDrawTimes;
private volatile DrawHandler handler;
private LinkedList<Long> mDrawTimes;
private Object mDrawMonitor;
private Callback mCallback;
private boolean mEnableDrawingCache;
private boolean isSurfaceCreated;
private boolean mDanmakuVisible;
@ -137,6 +138,11 @@ public class DanmakuView extends View implements IDanmakuView, IDanmakuViewContr
mCallback = callback;
}
public void setSpeed(float speed) {
if (getConfig() == null) return;
getConfig().setSpeed(speed);
}
@Override
public void release() {
stop();

@ -1,115 +1,14 @@
package tv.cjump.jni;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.util.Log;
import java.lang.reflect.Field;
public class NativeBitmapFactory {
static Field nativeIntField = null;
static {
System.loadLibrary("ndkbitmap");
}
public static void loadLibs() {
boolean libInit = init();
if (!libInit) {
release();
} else {
initField();
if (!testLib()) release();
}
}
public static synchronized void releaseLibs() {
nativeIntField = null;
release();
}
static void initField() {
try {
nativeIntField = Bitmap.Config.class.getDeclaredField("nativeInt");
nativeIntField.setAccessible(true);
} catch (NoSuchFieldException e) {
nativeIntField = null;
e.printStackTrace();
}
}
private static boolean testLib() {
if (nativeIntField == null) return false;
Bitmap bitmap = null;
Canvas canvas;
try {
bitmap = createNativeBitmap(2, 2, Bitmap.Config.ARGB_8888, true);
boolean result = (bitmap != null && bitmap.getWidth() == 2 && bitmap.getHeight() == 2);
if (result) {
if (Build.VERSION.SDK_INT >= 17 && !bitmap.isPremultiplied()) {
bitmap.setPremultiplied(true);
}
canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setTextSize(20f);
canvas.drawRect(0f, 0f, (float) bitmap.getWidth(), (float) bitmap.getHeight(), paint);
canvas.drawText("TestLib", 0, 0, paint);
if (Build.VERSION.SDK_INT >= 17) {
result = bitmap.isPremultiplied();
}
}
return result;
} catch (Exception e) {
Log.e("NativeBitmapFactory", "exception:" + e.toString());
return false;
} catch (Error e) {
return false;
} finally {
if (bitmap != null) {
bitmap.recycle();
}
}
}
public static int getNativeConfig(Bitmap.Config config) {
try {
if (nativeIntField == null) return 0;
return nativeIntField.getInt(config);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
return 0;
}
}
public static Bitmap createBitmap(int width, int height, Bitmap.Config config) {
return createBitmap(width, height, config, config.equals(Bitmap.Config.ARGB_4444) || config.equals(Bitmap.Config.ARGB_8888));
}
public static void recycle(Bitmap bitmap) {
bitmap.recycle();
}
public static synchronized Bitmap createBitmap(int width, int height, Bitmap.Config config, boolean hasAlpha) {
if (nativeIntField == null) return Bitmap.createBitmap(width, height, config);
return createNativeBitmap(width, height, config, hasAlpha);
return Bitmap.createBitmap(width, height, config, hasAlpha);
}
private static Bitmap createNativeBitmap(int width, int height, Config config, boolean hasAlpha) {
int nativeConfig = getNativeConfig(config);
return Build.VERSION.SDK_INT == 19 ? createBitmap19(width, height, nativeConfig, hasAlpha) : createBitmap(width, height, nativeConfig, hasAlpha);
}
private static native boolean init();
private static native boolean release();
private static native Bitmap createBitmap(int width, int height, int nativeConfig, boolean hasAlpha);
private static native Bitmap createBitmap19(int width, int height, int nativeConfig, boolean hasAlpha);
}

Loading…
Cancel
Save