Support danmu - part 2

pull/142/head
FongMi 3 years ago
parent 2610e4a45d
commit 2a131a0ecd
  1. 48
      app/src/main/java/com/fongmi/android/tv/bean/Danmu.java
  2. 16
      app/src/main/java/com/fongmi/android/tv/bean/Result.java
  3. 11
      app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java
  4. 44
      app/src/main/java/com/fongmi/android/tv/player/danmu/Parser.java
  5. 7
      app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java
  6. 50
      catvod/src/main/java/com/github/catvod/net/DeflateInterceptor.java
  7. 2
      catvod/src/main/java/com/github/catvod/net/OkHttp.java
  8. 38
      danmaku/src/main/java/master/flame/danmaku/danmaku/loader/ILoader.java
  9. 28
      danmaku/src/main/java/master/flame/danmaku/danmaku/loader/IllegalDataException.java
  10. 56
      danmaku/src/main/java/master/flame/danmaku/danmaku/loader/android/AcFunDanmakuLoader.java
  11. 58
      danmaku/src/main/java/master/flame/danmaku/danmaku/loader/android/BiliDanmakuLoader.java
  12. 34
      danmaku/src/main/java/master/flame/danmaku/danmaku/loader/android/DanmakuLoaderFactory.java
  13. 39
      danmaku/src/main/java/master/flame/danmaku/danmaku/model/BaseDanmaku.java
  14. 63
      danmaku/src/main/java/master/flame/danmaku/danmaku/model/android/DanmakuFactory.java
  15. 1
      danmaku/src/main/java/master/flame/danmaku/danmaku/model/android/Danmakus.java
  16. 20
      danmaku/src/main/java/master/flame/danmaku/danmaku/parser/BaseDanmakuParser.java
  17. 28
      danmaku/src/main/java/master/flame/danmaku/danmaku/parser/IDataSource.java
  18. 95
      danmaku/src/main/java/master/flame/danmaku/danmaku/parser/android/AndroidFileSource.java
  19. 78
      danmaku/src/main/java/master/flame/danmaku/danmaku/parser/android/JSONSource.java

@ -0,0 +1,48 @@
package com.fongmi.android.tv.bean;
import android.text.TextUtils;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.Text;
import org.simpleframework.xml.core.Persister;
import java.util.Collections;
import java.util.List;
@Root(name = "i", strict = false)
public class Danmu {
@ElementList(entry = "d", required = false, inline = true)
private List<D> d;
public static Danmu fromXml(String str) {
try {
return new Persister().read(Danmu.class, str);
} catch (Exception e) {
return new Danmu();
}
}
public List<D> getD() {
return d == null ? Collections.emptyList() : d;
}
public static class D {
@Attribute(name = "p", required = false)
public String p;
@Text
public String t;
public String getP() {
return TextUtils.isEmpty(p) ? "" : p;
}
public String getT() {
return TextUtils.isEmpty(t) ? "" : t;
}
}
}

@ -60,6 +60,8 @@ public class Result implements Parcelable {
private Integer jx;
@SerializedName("flag")
private String flag;
@SerializedName("danmaku")
private String danmaku;
@SerializedName("format")
private String format;
@SerializedName("url")
@ -77,6 +79,8 @@ public class Result implements Parcelable {
@SerializedName("msg")
private String msg;
private Danmu danmu;
public static Result objectFrom(String str) {
try {
return new Gson().fromJson(str, Result.class);
@ -191,8 +195,8 @@ public class Result implements Parcelable {
return jx == null ? 0 : jx;
}
public void setJx(Integer jx) {
this.jx = jx;
public String getDanmaku() {
return TextUtils.isEmpty(danmaku) ? "" : danmaku;
}
public String getFormat() {
@ -247,6 +251,14 @@ public class Result implements Parcelable {
this.msg = msg;
}
public Danmu getDanmu() {
return danmu == null ? new Danmu() : danmu;
}
public void setDanmu(Danmu danmu) {
this.danmu = danmu;
}
public boolean hasMsg() {
return getMsg().length() > 0;
}

@ -11,6 +11,7 @@ import com.fongmi.android.tv.App;
import com.fongmi.android.tv.Constant;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.api.ApiConfig;
import com.fongmi.android.tv.bean.Danmu;
import com.fongmi.android.tv.bean.Episode;
import com.fongmi.android.tv.bean.Flag;
import com.fongmi.android.tv.bean.Result;
@ -47,6 +48,7 @@ public class SiteViewModel extends ViewModel {
public MutableLiveData<Result> result;
public MutableLiveData<Result> player;
public MutableLiveData<Result> search;
public MutableLiveData<Danmu> danmaku;
public ExecutorService executor;
public SiteViewModel() {
@ -157,6 +159,7 @@ public class SiteViewModel extends ViewModel {
Result result = Result.fromJson(playerContent);
if (result.getFlag().isEmpty()) result.setFlag(flag);
result.setUrl(Source.get().fetch(result));
checkDanmaku(result);
result.setKey(key);
return result;
} else if (site.getType() == 4) {
@ -168,6 +171,7 @@ public class SiteViewModel extends ViewModel {
Result result = Result.fromJson(playerContent);
if (result.getFlag().isEmpty()) result.setFlag(flag);
result.setUrl(Source.get().fetch(result));
checkDanmaku(result);
return result;
} else if (site.isEmpty() && key.equals("push_agent")) {
Result result = new Result();
@ -267,6 +271,13 @@ public class SiteViewModel extends ViewModel {
}
}
private void checkDanmaku(Result result) throws Exception {
if (result.getDanmaku().isEmpty()) return;
String body = OkHttp.newCall(result.getDanmaku()).execute().body().string();
result.setDanmu(Danmu.fromXml(body));
SpiderDebug.log(body);
}
private void post(Site site, Result result) {
if (result.getList().isEmpty()) return;
for (Vod vod : result.getList()) vod.setSite(site);

@ -0,0 +1,44 @@
package com.fongmi.android.tv.player.danmu;
import android.graphics.Color;
import com.fongmi.android.tv.bean.Danmu;
import master.flame.danmaku.danmaku.model.BaseDanmaku;
import master.flame.danmaku.danmaku.model.IDanmakus;
import master.flame.danmaku.danmaku.model.android.Danmakus;
import master.flame.danmaku.danmaku.parser.BaseDanmakuParser;
public class Parser extends BaseDanmakuParser {
private final Danmu danmu;
public Parser(Danmu danmu) {
this.danmu = danmu;
}
@Override
protected Danmakus parse() {
Danmakus result = new Danmakus(IDanmakus.ST_BY_TIME);
for (Danmu.D d : danmu.getD()) {
String[] values = d.getP().split(",");
if (values.length < 8) continue;
int type = Integer.parseInt(values[1]);
long time = (long) (Float.parseFloat(values[0]) * 1000);
float size = Float.parseFloat(values[2]) * (mDispDensity - 0.6f);
int color = (int) ((0x00000000ff000000L | Long.parseLong(values[3])) & 0x00000000ffffffffL);
BaseDanmaku item = mContext.mDanmakuFactory.createDanmaku(type, mContext);
item.setTime(time);
item.setTimer(mTimer);
item.setTextSize(size);
item.setTextColor(color);
item.setTextShadowColor(color <= Color.BLACK ? Color.WHITE : Color.BLACK);
item.setFlags(mContext.mGlobalFlagValues);
Object lock = result.obtainSynchronizer();
synchronized (lock) {
result.addItem(item);
}
}
return result;
}
}

@ -40,6 +40,7 @@ import com.fongmi.android.tv.Constant;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.Setting;
import com.fongmi.android.tv.api.ApiConfig;
import com.fongmi.android.tv.bean.Danmu;
import com.fongmi.android.tv.bean.Episode;
import com.fongmi.android.tv.bean.Flag;
import com.fongmi.android.tv.bean.History;
@ -508,6 +509,12 @@ 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.getDanmu());
}
private void loadDanmu(Danmu danmu) {
if (danmu.getD().isEmpty()) return;
}
@Override

@ -0,0 +1,50 @@
package com.github.catvod.net;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.common.net.HttpHeaders;
import java.io.IOException;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.BufferedSource;
import okio.Okio;
public class DeflateInterceptor implements Interceptor {
@NonNull
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
return deflate(chain.proceed(chain.request()));
}
private Response deflate(Response response) {
String encoding = response.header(HttpHeaders.CONTENT_ENCODING);
if (response.body() == null || encoding == null || !encoding.equals("deflate")) return response;
InflaterInputStream is = new InflaterInputStream(response.body().byteStream(), new Inflater(true));
return response.newBuilder().headers(response.headers()).body(new ResponseBody() {
@Nullable
@Override
public MediaType contentType() {
return response.body().contentType();
}
@Override
public long contentLength() {
return response.body().contentLength();
}
@NonNull
@Override
public BufferedSource source() {
return Okio.buffer(Okio.source(is));
}
}).build();
}
}

@ -63,7 +63,7 @@ public class OkHttp {
}
public static OkHttpClient client(int timeout) {
return new OkHttpClient.Builder().connectTimeout(timeout, TimeUnit.MILLISECONDS).readTimeout(timeout, TimeUnit.MILLISECONDS).writeTimeout(timeout, TimeUnit.MILLISECONDS).dns(dns()).hostnameVerifier(SSLCompat.VERIFIER).sslSocketFactory(new SSLCompat(), SSLCompat.TM).build();
return new OkHttpClient.Builder().addInterceptor(new DeflateInterceptor()).connectTimeout(timeout, TimeUnit.MILLISECONDS).readTimeout(timeout, TimeUnit.MILLISECONDS).writeTimeout(timeout, TimeUnit.MILLISECONDS).dns(dns()).hostnameVerifier(SSLCompat.VERIFIER).sslSocketFactory(new SSLCompat(), SSLCompat.TM).build();
}
public static Call newCall(String url) {

@ -1,38 +0,0 @@
/*
* Copyright (C) 2013 Chen Hui <calmer91@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package master.flame.danmaku.danmaku.loader;
import java.io.InputStream;
import master.flame.danmaku.danmaku.parser.IDataSource;
public interface ILoader {
/**
* @return data source
*/
IDataSource<?> getDataSource();
/**
* @param uri 弹幕文件地址(http:// file://)
*/
void load(String uri) throws IllegalDataException;
/**
* @param in stream from Internet or local file
*/
void load(InputStream in) throws IllegalDataException;
}

@ -1,28 +0,0 @@
package master.flame.danmaku.danmaku.loader;
/**
* Thrown when data is loading which can not be reasonably deal with.
*
* @author yrom
*/
public class IllegalDataException extends Exception {
private static final long serialVersionUID = 10441759254L;
public IllegalDataException() {
super();
}
public IllegalDataException(String detailMessage, Throwable throwable) {
super(detailMessage, throwable);
}
public IllegalDataException(String detailMessage) {
super(detailMessage);
}
public IllegalDataException(Throwable throwable) {
super(throwable);
}
}

@ -1,56 +0,0 @@
package master.flame.danmaku.danmaku.loader.android;
import android.net.Uri;
import java.io.InputStream;
import master.flame.danmaku.danmaku.loader.ILoader;
import master.flame.danmaku.danmaku.loader.IllegalDataException;
import master.flame.danmaku.danmaku.parser.android.JSONSource;
/**
* Ac danmaku loader
*
* @author yrom
*/
public class AcFunDanmakuLoader implements ILoader {
private static volatile AcFunDanmakuLoader instance;
private JSONSource dataSource;
private AcFunDanmakuLoader() {
}
public static ILoader instance() {
if (instance == null) {
synchronized (AcFunDanmakuLoader.class) {
if (instance == null)
instance = new AcFunDanmakuLoader();
}
}
return instance;
}
@Override
public JSONSource getDataSource() {
return dataSource;
}
@Override
public void load(String uri) throws IllegalDataException {
try {
dataSource = new JSONSource(Uri.parse(uri));
} catch (Exception e) {
throw new IllegalDataException(e);
}
}
@Override
public void load(InputStream in) throws IllegalDataException {
try {
dataSource = new JSONSource(in);
} catch (Exception e) {
throw new IllegalDataException(e);
}
}
}

@ -1,58 +0,0 @@
/*
* Copyright (C) 2013 Chen Hui <calmer91@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package master.flame.danmaku.danmaku.loader.android;
import java.io.InputStream;
import master.flame.danmaku.danmaku.loader.ILoader;
import master.flame.danmaku.danmaku.loader.IllegalDataException;
import master.flame.danmaku.danmaku.parser.android.AndroidFileSource;
public class BiliDanmakuLoader implements ILoader {
private static BiliDanmakuLoader _instance;
private AndroidFileSource dataSource;
private BiliDanmakuLoader() {
}
public static BiliDanmakuLoader instance() {
if (_instance == null) {
_instance = new BiliDanmakuLoader();
}
return _instance;
}
public void load(String uri) throws IllegalDataException {
try {
dataSource = new AndroidFileSource(uri);
} catch (Exception e) {
throw new IllegalDataException(e);
}
}
public void load(InputStream stream) {
dataSource = new AndroidFileSource(stream);
}
@Override
public AndroidFileSource getDataSource() {
return dataSource;
}
}

@ -1,34 +0,0 @@
/*
* Copyright (C) 2013 Chen Hui <calmer91@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package master.flame.danmaku.danmaku.loader.android;
import master.flame.danmaku.danmaku.loader.ILoader;
public class DanmakuLoaderFactory {
public static String TAG_BILI = "bili";
public static String TAG_ACFUN = "acfun";
public static ILoader create(String tag) {
if (TAG_BILI.equalsIgnoreCase(tag)) {
return BiliDanmakuLoader.instance();
} else if (TAG_ACFUN.equalsIgnoreCase(tag))
return AcFunDanmakuLoader.instance();
return null;
}
}

@ -32,8 +32,6 @@ public abstract class BaseDanmaku {
public final static int TYPE_SPECIAL = 7;
public final static int TYPE_MOVEABLE_XXX = 0; // TODO: add more type
public final static int INVISIBLE = 0;
public final static int VISIBLE = 1;
@ -193,8 +191,7 @@ public abstract class BaseDanmaku {
}
public boolean isMeasured() {
return paintWidth > -1 && paintHeight > -1
&& measureResetFlag == flags.MEASURE_RESET_FLAG;
return paintWidth > -1 && paintHeight > -1 && measureResetFlag == flags.MEASURE_RESET_FLAG;
}
public void measure(IDisplayer displayer, boolean fromWorkerThread) {
@ -216,8 +213,7 @@ public abstract class BaseDanmaku {
}
public boolean isShown() {
return this.visibility == VISIBLE
&& visibleResetFlag == flags.VISIBLE_RESET_FLAG;
return this.visibility == VISIBLE && visibleResetFlag == flags.VISIBLE_RESET_FLAG;
}
public boolean isTimeOut() {
@ -261,8 +257,9 @@ public abstract class BaseDanmaku {
if (b) {
this.visibleResetFlag = flags.VISIBLE_RESET_FLAG;
this.visibility = VISIBLE;
} else
} else {
this.visibility = INVISIBLE;
}
}
public abstract void layout(IDisplayer displayer, float x, float y);
@ -306,9 +303,7 @@ public abstract class BaseDanmaku {
}
public Object getTag(int key) {
if (mTags == null) {
return null;
}
if (mTags == null) return null;
return mTags.get(key);
}
@ -326,6 +321,30 @@ public abstract class BaseDanmaku {
this.timeOffset = 0;
}
public void setText(CharSequence text) {
this.text = text;
}
public void setTextColor(int textColor) {
this.textColor = textColor;
}
public void setTextShadowColor(int textShadowColor) {
this.textShadowColor = textShadowColor;
}
public void setTextSize(float textSize) {
this.textSize = textSize;
}
public void setIndex(int index) {
this.index = index;
}
public void setFlags(GlobalFlagValues flags) {
this.flags = flags;
}
public long getActualTime() {
if (flags == null || flags.SYNC_TIME_OFFSET_RESET_FLAG != this.syncTimeOffsetResetFlag) {
this.timeOffset = 0;

@ -62,11 +62,8 @@ public class DanmakuFactory {
return new DanmakuFactory();
}
public static void fillLinePathData(BaseDanmaku item, float[][] points, float scaleX,
float scaleY) {
if (item.getType() != BaseDanmaku.TYPE_SPECIAL || points.length == 0
|| points[0].length != 2)
return;
public static void fillLinePathData(BaseDanmaku item, float[][] points, float scaleX, float scaleY) {
if (item.getType() != BaseDanmaku.TYPE_SPECIAL || points.length == 0 || points[0].length != 2) return;
for (int i = 0; i < points.length; i++) {
points[i][0] *= scaleX;
points[i][1] *= scaleY;
@ -94,16 +91,14 @@ public class DanmakuFactory {
}
public BaseDanmaku createDanmaku(int type, DanmakuContext context) {
if (context == null)
return null;
if (context == null) return null;
sLastConfig = context;
sLastDisp = context.getDisplayer();
return createDanmaku(type, sLastDisp.getWidth(), sLastDisp.getHeight(), CURRENT_DISP_SIZE_FACTOR, context.scrollSpeedFactor);
}
public BaseDanmaku createDanmaku(int type, IDisplayer disp, float viewportScale, float scrollSpeedFactor) {
if (disp == null)
return null;
if (disp == null) return null;
sLastDisp = disp;
return createDanmaku(type, disp.getWidth(), disp.getHeight(), viewportScale, scrollSpeedFactor);
}
@ -117,8 +112,7 @@ public class DanmakuFactory {
* @param viewportScale 缩放比例,会影响滚动弹幕的存活时间(duration)
* @return
*/
public BaseDanmaku createDanmaku(int type, int viewportWidth, int viewportHeight,
float viewportScale, float scrollSpeedFactor) {
public BaseDanmaku createDanmaku(int type, int viewportWidth, int viewportHeight, float viewportScale, float scrollSpeedFactor) {
return createDanmaku(type, (float) viewportWidth, (float) viewportHeight, viewportScale, scrollSpeedFactor);
}
@ -131,8 +125,7 @@ public class DanmakuFactory {
* @param viewportSizeFactor 会影响滚动弹幕的速度/存活时间(duration)
* @return
*/
public BaseDanmaku createDanmaku(int type, float viewportWidth, float viewportHeight,
float viewportSizeFactor, float scrollSpeedFactor) {
public BaseDanmaku createDanmaku(int type, float viewportWidth, float viewportHeight, float viewportSizeFactor, float scrollSpeedFactor) {
int oldDispWidth = CURRENT_DISP_WIDTH;
int oldDispHeight = CURRENT_DISP_HEIGHT;
boolean sizeChanged = updateViewportState(viewportWidth, viewportHeight, viewportSizeFactor);
@ -185,25 +178,17 @@ public class DanmakuFactory {
}
private void updateScaleFactor(int width, int height, float scaleX, float scaleY) {
if (mScaleFactor == null) {
mScaleFactor = new SpecialDanmaku.ScaleFactor(width, height, scaleX, scaleY);
}
if (mScaleFactor == null) mScaleFactor = new SpecialDanmaku.ScaleFactor(width, height, scaleX, scaleY);
mScaleFactor.update(width, height, scaleX, scaleY);
}
public boolean updateViewportState(float viewportWidth, float viewportHeight,
float viewportSizeFactor) {
public boolean updateViewportState(float viewportWidth, float viewportHeight, float viewportSizeFactor) {
boolean sizeChanged = false;
if (CURRENT_DISP_WIDTH != (int) viewportWidth
|| CURRENT_DISP_HEIGHT != (int) viewportHeight
|| CURRENT_DISP_SIZE_FACTOR != viewportSizeFactor) {
if (CURRENT_DISP_WIDTH != (int) viewportWidth || CURRENT_DISP_HEIGHT != (int) viewportHeight || CURRENT_DISP_SIZE_FACTOR != viewportSizeFactor) {
sizeChanged = true;
REAL_DANMAKU_DURATION = (long) (COMMON_DANMAKU_DURATION * (viewportSizeFactor
* viewportWidth / BILI_PLAYER_WIDTH));
REAL_DANMAKU_DURATION = Math.min(MAX_DANMAKU_DURATION_HIGH_DENSITY,
REAL_DANMAKU_DURATION);
REAL_DANMAKU_DURATION = (long) (COMMON_DANMAKU_DURATION * (viewportSizeFactor * 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);
CURRENT_DISP_WIDTH = (int) viewportWidth;
CURRENT_DISP_HEIGHT = (int) viewportHeight;
CURRENT_DISP_SIZE_FACTOR = viewportSizeFactor;
@ -218,20 +203,15 @@ public class DanmakuFactory {
}
public void updateMaxDanmakuDuration() {
long maxScrollDuration = (MAX_Duration_Scroll_Danmaku == null ? 0 : MAX_Duration_Scroll_Danmaku.value),
maxFixDuration = (MAX_Duration_Fix_Danmaku == null ? 0 : MAX_Duration_Fix_Danmaku.value),
maxSpecialDuration = (MAX_Duration_Special_Danmaku == null ? 0 : MAX_Duration_Special_Danmaku.value);
long maxScrollDuration = (MAX_Duration_Scroll_Danmaku == null ? 0 : MAX_Duration_Scroll_Danmaku.value), maxFixDuration = (MAX_Duration_Fix_Danmaku == null ? 0 : MAX_Duration_Fix_Danmaku.value), maxSpecialDuration = (MAX_Duration_Special_Danmaku == null ? 0 : MAX_Duration_Special_Danmaku.value);
MAX_DANMAKU_DURATION = Math.max(maxScrollDuration, maxFixDuration);
MAX_DANMAKU_DURATION = Math.max(MAX_DANMAKU_DURATION, maxSpecialDuration);
MAX_DANMAKU_DURATION = Math.max(COMMON_DANMAKU_DURATION, MAX_DANMAKU_DURATION);
MAX_DANMAKU_DURATION = Math.max(REAL_DANMAKU_DURATION, MAX_DANMAKU_DURATION);
}
public void updateDurationFactor(float f) {
if (MAX_Duration_Scroll_Danmaku == null || MAX_Duration_Fix_Danmaku == null)
return;
if (MAX_Duration_Scroll_Danmaku == null || MAX_Duration_Fix_Danmaku == null) return;
MAX_Duration_Scroll_Danmaku.setFactor(f);
updateMaxDanmakuDuration();
}
@ -248,13 +228,9 @@ public class DanmakuFactory {
* @param translationDuration
* @param translationStartDelay
*/
public void fillTranslationData(BaseDanmaku item, float beginX, float beginY,
float endX, float endY, long translationDuration, long translationStartDelay,
float scaleX, float scaleY) {
if (item.getType() != BaseDanmaku.TYPE_SPECIAL)
return;
((SpecialDanmaku) item).setTranslationData(beginX * scaleX, beginY * scaleY, endX * scaleX,
endY * scaleY, translationDuration, translationStartDelay);
public void fillTranslationData(BaseDanmaku item, float beginX, float beginY, float endX, float endY, long translationDuration, long translationStartDelay, float scaleX, float scaleY) {
if (item.getType() != BaseDanmaku.TYPE_SPECIAL) return;
((SpecialDanmaku) item).setTranslationData(beginX * scaleX, beginY * scaleY, endX * scaleX, endY * scaleY, translationDuration, translationStartDelay);
updateSpecicalDanmakuDuration(item);
}
@ -266,10 +242,8 @@ public class DanmakuFactory {
* @param endAlpha
* @param alphaDuraion
*/
public void fillAlphaData(BaseDanmaku item, int beginAlpha, int endAlpha,
long alphaDuraion) {
if (item.getType() != BaseDanmaku.TYPE_SPECIAL)
return;
public void fillAlphaData(BaseDanmaku item, int beginAlpha, int endAlpha, long alphaDuraion) {
if (item.getType() != BaseDanmaku.TYPE_SPECIAL) return;
((SpecialDanmaku) item).setAlphaData(beginAlpha, endAlpha, alphaDuraion);
updateSpecicalDanmakuDuration(item);
}
@ -280,5 +254,4 @@ public class DanmakuFactory {
updateMaxDanmakuDuration();
}
}
}

@ -323,5 +323,4 @@ public class Danmakus implements IDanmakus {
public Object obtainSynchronizer() {
return mLockObject;
}
}

@ -22,12 +22,8 @@ import master.flame.danmaku.danmaku.model.IDanmakus;
import master.flame.danmaku.danmaku.model.IDisplayer;
import master.flame.danmaku.danmaku.model.android.DanmakuContext;
/**
*
*/
public abstract class BaseDanmakuParser {
protected IDataSource<?> mDataSource;
protected DanmakuTimer mTimer;
protected int mDispWidth;
protected int mDispHeight;
@ -67,11 +63,6 @@ public abstract class BaseDanmakuParser {
return 1 / (mDispDensity - 0.6f);
}
public BaseDanmakuParser load(IDataSource<?> source) {
mDataSource = source;
return this;
}
public DanmakuTimer getTimer() {
return mTimer;
}
@ -82,25 +73,16 @@ public abstract class BaseDanmakuParser {
}
public IDanmakus getDanmakus() {
if (mDanmakus != null)
return mDanmakus;
if (mDanmakus != null) return mDanmakus;
mContext.mDanmakuFactory.resetDurationsData();
mDanmakus = parse();
releaseDataSource();
mContext.mDanmakuFactory.updateMaxDanmakuDuration();
return mDanmakus;
}
protected void releaseDataSource() {
if (mDataSource != null)
mDataSource.release();
mDataSource = null;
}
protected abstract IDanmakus parse();
public void release() {
releaseDataSource();
}
public BaseDanmakuParser setConfig(DanmakuContext config) {

@ -1,28 +0,0 @@
/*
* Copyright (C) 2013 Chen Hui <calmer91@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package master.flame.danmaku.danmaku.parser;
public interface IDataSource<T> {
String SCHEME_HTTP_TAG = "http";
String SCHEME_HTTPS_TAG = "https";
String SCHEME_FILE_TAG = "file";
public T data();
public void release();
}

@ -1,95 +0,0 @@
/*
* Copyright (C) 2013 Chen Hui <calmer91@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package master.flame.danmaku.danmaku.parser.android;
import android.net.Uri;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import master.flame.danmaku.danmaku.parser.IDataSource;
import master.flame.danmaku.danmaku.util.IOUtils;
public class AndroidFileSource implements IDataSource<InputStream> {
private InputStream inStream;
public AndroidFileSource(String filepath) {
fillStreamFromFile(new File(filepath));
}
public AndroidFileSource(Uri uri) {
fillStreamFromUri(uri);
}
public AndroidFileSource(File file) {
fillStreamFromFile(file);
}
public AndroidFileSource(InputStream stream) {
this.inStream = stream;
}
public void fillStreamFromFile(File file) {
try {
inStream = new BufferedInputStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void fillStreamFromUri(Uri uri) {
String scheme = uri.getScheme();
if (SCHEME_HTTP_TAG.equalsIgnoreCase(scheme) || SCHEME_HTTPS_TAG.equalsIgnoreCase(scheme)) {
fillStreamFromHttpFile(uri);
} else if (SCHEME_FILE_TAG.equalsIgnoreCase(scheme)) {
fillStreamFromFile(new File(uri.getPath()));
}
}
public void fillStreamFromHttpFile(Uri uri) {
try {
URL url = new URL(uri.getPath());
url.openConnection();
inStream = new BufferedInputStream(url.openStream());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void release() {
IOUtils.closeQuietly(inStream);
inStream = null;
}
@Override
public InputStream data() {
return inStream;
}
}

@ -1,78 +0,0 @@
package master.flame.danmaku.danmaku.parser.android;
import android.net.Uri;
import android.text.TextUtils;
import org.json.JSONArray;
import org.json.JSONException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import master.flame.danmaku.danmaku.parser.IDataSource;
import master.flame.danmaku.danmaku.util.IOUtils;
/**
* a json file source
*
* @author yrom
*/
public class JSONSource implements IDataSource<JSONArray> {
private JSONArray mJSONArray;
private InputStream mInput;
public JSONSource(String json) throws JSONException {
init(json);
}
public JSONSource(InputStream in) throws JSONException {
init(in);
}
public JSONSource(URL url) throws JSONException, IOException {
this(url.openStream());
}
public JSONSource(File file) throws FileNotFoundException, JSONException {
init(new FileInputStream(file));
}
public JSONSource(Uri uri) throws IOException, JSONException {
String scheme = uri.getScheme();
if (SCHEME_HTTP_TAG.equalsIgnoreCase(scheme) || SCHEME_HTTPS_TAG.equalsIgnoreCase(scheme)) {
init(new URL(uri.getPath()).openStream());
} else if (SCHEME_FILE_TAG.equalsIgnoreCase(scheme)) {
init(new FileInputStream(uri.getPath()));
}
}
private void init(InputStream in) throws JSONException {
if (in == null)
throw new NullPointerException("input stream cannot be null!");
mInput = in;
String json = IOUtils.getString(mInput);
init(json);
}
private void init(String json) throws JSONException {
if (!TextUtils.isEmpty(json)) {
mJSONArray = new JSONArray(json);
}
}
public JSONArray data() {
return mJSONArray;
}
@Override
public void release() {
IOUtils.closeQuietly(mInput);
mInput = null;
mJSONArray = null;
}
}
Loading…
Cancel
Save