278 lines
13 KiB
Java
278 lines
13 KiB
Java
package com.xixun.xixunplayer;
|
|
|
|
import android.annotation.SuppressLint;
|
|
import android.content.Context;
|
|
import android.net.Uri;
|
|
import android.view.View;
|
|
import android.webkit.WebView;
|
|
import android.webkit.WebViewClient;
|
|
import android.widget.ImageView;
|
|
|
|
import java.io.File;
|
|
import java.time.LocalDate;
|
|
import java.time.LocalTime;
|
|
import java.util.ArrayList;
|
|
import java.util.HashSet;
|
|
|
|
import gnph.util.Dates;
|
|
import gnph.util.JSList;
|
|
import gnph.util.JSMap;
|
|
import pl.droidsonroids.gif.GifImageView;
|
|
|
|
@SuppressLint("ViewConstructor")
|
|
public class Prog extends AbsLayout {
|
|
|
|
ArrayList<Page> pages = new ArrayList<>();
|
|
ArrayList<Integer> avas = new ArrayList<>();
|
|
HashSet<Source> toBeHided = new HashSet<>();
|
|
|
|
public Prog(JSMap task, Context context) {
|
|
super(context);
|
|
JSList<JSMap> jpages = task.jslist("items");
|
|
for(var pageMap : jpages) {
|
|
var _program = pageMap.jsmap("_program");
|
|
JSList<JSMap> layers = _program.jslist("layers");
|
|
if(layers.isEmpty()) continue;
|
|
JSList<Long> splitWidths = _program.jslist("splitWidths");
|
|
var page = new Page();
|
|
page.repeatTimes = pageMap.intg("repeatTimes");
|
|
page.parse(pageMap.jslist("schedules"));
|
|
for(int ll=layers.size()-1; ll>=0; ll--) {
|
|
var layer = new Layer();
|
|
layer.isLoop = layers.get(ll).bool("repeat");
|
|
JSList<JSMap> sources = layers.get(ll).jslist("sources");
|
|
var border = layers.get(ll).jsmap("border");
|
|
EleBorder bdEle = null;
|
|
int bdWidth = 0, bdStart = 0xffff, bdEnd = 0;
|
|
if(border!=null) {
|
|
bdEle = new EleBorder(Util.programDir+"/"+border.stnn("img"), border.stnn("eff"), border.intg("speed"), context);
|
|
bdWidth = bdEle.img.getHeight();
|
|
}
|
|
var ele = new Source();
|
|
int x, y, w, h;
|
|
String id;
|
|
for(var source : sources) {
|
|
ele.type = source.stnn("_type");
|
|
if(ele.type.isEmpty()) continue;
|
|
var timeSpan = source.intg("timeSpan")*1000;
|
|
if(timeSpan==0) continue;
|
|
x = source.intg("left")+bdWidth;
|
|
y = source.intg("top")+bdWidth;
|
|
w = source.intg("width")-bdWidth-bdWidth;
|
|
h = source.intg("height")-bdWidth-bdWidth;
|
|
boolean notAudio = ! ele.type.equals("Audio");
|
|
if((w<=0 || h<=0) && notAudio) continue;
|
|
ele.startTime = source.intg("playTime")*1000;
|
|
if(bdStart > ele.startTime) bdStart = ele.startTime;
|
|
ele.endTime = ele.startTime + timeSpan;
|
|
if(bdEnd < ele.endTime) bdEnd = ele.endTime;
|
|
if(layer.dur < ele.endTime) layer.dur = ele.endTime;
|
|
if(page.sDur < ele.endTime && notAudio) page.sDur = ele.endTime;
|
|
id = source.stnn("id");
|
|
ele.view = null;
|
|
if(ele.type.equals("Image")) {
|
|
var isGif = source.stnn("fileExt").equalsIgnoreCase("gif");
|
|
ImageView imgView = isGif ? new GifImageView(context) : new ImageView(context);
|
|
imgView.setImageURI(ele.uri = Uri.fromFile(new File(Util.programDir + "/" + id)));
|
|
imgView.setScaleType(ImageView.ScaleType.FIT_XY);
|
|
if(! isGif) ele.uri = null;
|
|
ele.view = imgView;
|
|
} else if(ele.type.equals("MultiPng")) {
|
|
JSList<JSMap> imgs = source.jslist("arrayPics");
|
|
if(imgs.isEmpty()) continue;
|
|
if(imgs.size()==1 && imgs.get(0).intg("picDuration")==0) ele.view = new EleScroll(Util.programDir+"/", imgs.get(0), context);
|
|
else ele.view = new EleFlip(Util.programDir+"/", imgs, context);
|
|
} else if(ele.type.equals("SplitText")) {
|
|
JSList<JSMap> imgs = source.jslist("arrayPics");
|
|
if(imgs.isEmpty()) continue;
|
|
ele.view = new AbsLayout(context);
|
|
var partHeight = _program.intg("height");
|
|
if(imgs.size()==1 && imgs.get(0).intg("picDuration")==0) {
|
|
var view = new EleScroll(Util.programDir+"/", imgs.get(0), context);
|
|
((AbsLayout) ele.view).addView(view, new AbsLayout.LayoutParams(x, y, splitWidths.get(0).intValue(), h));
|
|
view.others = new ArrayList<>();
|
|
for(int i=1; i<splitWidths.size(); i++) {
|
|
x -= splitWidths.get(i-1);
|
|
y += partHeight;
|
|
var split = new EleOtherPart(context, view);
|
|
((AbsLayout) ele.view).addView(split, new AbsLayout.LayoutParams(x, y, splitWidths.get(i).intValue() - x, h));
|
|
view.others.add(split);
|
|
}
|
|
} else {
|
|
var view = new EleFlip(Util.programDir+"/", imgs, context);
|
|
((AbsLayout) ele.view).addView(view, new AbsLayout.LayoutParams(x, y, splitWidths.get(0).intValue(), h));
|
|
view.others = new ArrayList<>();
|
|
for(int i=1; i<splitWidths.size(); i++) {
|
|
x -= splitWidths.get(i-1);
|
|
y += partHeight;
|
|
var split = new EleOtherPart(context, view);
|
|
((AbsLayout) ele.view).addView(split, new AbsLayout.LayoutParams(x, y, splitWidths.get(i).intValue() - x, h));
|
|
view.others.add(split);
|
|
}
|
|
}
|
|
w = 0;
|
|
} else if(ele.type.equals("DigitalClockNew")) ele.view = new EleDigiClock(Util.programDir+"/", source, context);
|
|
else if(ele.type.equals("AnalogClock")) ele.view = new EleAnaClock(w, h, Util.programDir + "/" + id, source, context);
|
|
else if(ele.type.equals("Video") || ele.type.equals("Audio")) ele.view = new EleVideo(context, Util.programDir + "/" +id, source.intg("vol", 100) / 100.0f);
|
|
else if(ele.type.equals("WebURL")) {
|
|
var webView = new WebView(context);
|
|
webView.setWebViewClient(new WebViewClient() {
|
|
@Override
|
|
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
|
return false;
|
|
}
|
|
});
|
|
webView.loadUrl(source.stnn("url"));
|
|
ele.view = webView;
|
|
}
|
|
else if(ele.type.equals("Timer")) ele.view = new EleTimer(Util.programDir+"/", source, context);
|
|
else if(ele.type.equals("EnvironmentalMonitoring")) ele.view = new EleEnviron(Util.programDir+"/", source, context);
|
|
else continue;
|
|
if(ele.view==null) continue;
|
|
if(w > 0) ele.view.setLayoutParams(new AbsLayout.LayoutParams(x, y, w, h));
|
|
ele.view.setVisibility(GONE);
|
|
addView(ele.view);
|
|
layer.eles.add(ele);
|
|
ele = new Source();
|
|
}
|
|
if(bdEle!=null && ! sources.isEmpty()) {
|
|
JSList<Long> geometry = border.jslist("geometry");
|
|
x = geometry.get(0).intValue();
|
|
y = geometry.get(1).intValue();
|
|
w = geometry.get(2).intValue();
|
|
h = geometry.get(3).intValue();
|
|
ele.startTime = bdStart;
|
|
ele.endTime = bdEnd;
|
|
ele.view = bdEle;
|
|
ele.view.setVisibility(GONE);
|
|
addView(ele.view, new AbsLayout.LayoutParams(x, y, w, h));
|
|
layer.eles.add(ele);
|
|
}
|
|
if(! layer.eles.isEmpty()) page.layers.add(layer);
|
|
}
|
|
if(page.sDur==0) continue;
|
|
page.tDur = page.sDur * page.repeatTimes;
|
|
for_layer: for(int ll=0; ll<page.layers.size(); ll++) {
|
|
var layer = page.layers.get(ll);
|
|
for(int ee=0; ee<layer.eles.size(); ee++) {
|
|
var ele = layer.eles.get(ee);
|
|
if(ele.startTime >= page.sDur) {
|
|
if(layer.eles.size() > 1) layer.eles.remove(ee--);
|
|
else {
|
|
page.layers.remove(ll--);
|
|
continue for_layer;
|
|
}
|
|
} else if(ele.endTime > page.sDur) ele.endTime = page.sDur;
|
|
}
|
|
if(layer.dur > page.sDur) layer.dur = page.sDur;
|
|
if(layer.dur == page.sDur) layer.isLoop = false;
|
|
}
|
|
pages.add(page);
|
|
}
|
|
}
|
|
|
|
void release() {
|
|
try {
|
|
setVisibility(GONE);
|
|
View view;
|
|
for(int cc=0; cc<getChildCount(); cc++) if((view = getChildAt(cc)) instanceof EleVideo) ((EleVideo) view).release();
|
|
} catch (Throwable e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
|
|
public static class Source {
|
|
View view;
|
|
long prepareMilli;
|
|
long startMilli;
|
|
long endMilli = Long.MAX_VALUE;
|
|
int startTime;
|
|
int endTime;
|
|
String type;
|
|
Uri uri;
|
|
|
|
void show() {
|
|
if(view.getVisibility()==VISIBLE) return;
|
|
view.setVisibility(VISIBLE);
|
|
}
|
|
void hide() {
|
|
if(view.getVisibility()!=VISIBLE) return;
|
|
view.setVisibility(GONE);
|
|
if(uri!=null) ((GifImageView) view).setImageURI(uri);
|
|
}
|
|
}
|
|
public static class Layer {
|
|
ArrayList<Source> eles = new ArrayList<>();
|
|
long endMilli = Long.MAX_VALUE;
|
|
int dur;
|
|
boolean isLoop;
|
|
}
|
|
|
|
public static class Sche {
|
|
long startDate = -1, endDate = -1;
|
|
int startTime = -1, endTime = -1;
|
|
JSList<Integer> weeks;
|
|
}
|
|
|
|
public static class Page {
|
|
ArrayList<Layer> layers = new ArrayList<>();
|
|
ArrayList<Sche> sches;
|
|
long endMilli = Long.MAX_VALUE;
|
|
int sDur, tDur, repeatTimes;
|
|
|
|
void hide() {
|
|
for(var layer : layers) for(var ele : layer.eles) ele.hide();
|
|
}
|
|
|
|
public void setMillis(long milli) {
|
|
endMilli = milli + sDur;
|
|
for(var layer : layers) {
|
|
if(layer.isLoop) layer.endMilli = milli + layer.dur;
|
|
for(var ele : layer.eles) {
|
|
ele.endMilli = milli + ele.endTime;
|
|
ele.startMilli = milli + ele.startTime;
|
|
if(ele.startTime == 0) ele.show();
|
|
}
|
|
}
|
|
}
|
|
public boolean isSchedule(long milli) {
|
|
if(sches==null) return true;
|
|
var local = milli + Dates.zoneOff;
|
|
var time = local % 86400000L;
|
|
var week = -1;
|
|
for(var sche : sches) {
|
|
if(notInRange(sche.startDate, local, sche.endDate)) continue;
|
|
if(notInRange(sche.startTime, time, sche.endTime)) continue;
|
|
if(sche.weeks==null) return true;
|
|
if(week==-1) week = LocalDate.ofEpochDay(local / 86400000L).getDayOfWeek().getValue();
|
|
if(sche.weeks.contains(week)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
public boolean notInRange(long start, long val, long end) {
|
|
if(end==-1) return false;
|
|
return start <= end ? !(val >= start && val < end) : val >= end && val < start;
|
|
}
|
|
|
|
public void parse(JSList<JSMap> schedules) {
|
|
if(schedules!=null) for(var schedule : schedules) {
|
|
var sche = new Sche();
|
|
var startTime = schedule.str("startTime");
|
|
if(startTime!=null) sche.startTime = LocalTime.parse(startTime).toSecondOfDay()*1000;
|
|
var endTime = schedule.str("endTime");
|
|
if(endTime!=null) sche.endTime = LocalTime.parse(endTime).toSecondOfDay()*1000;
|
|
if(sche.startTime==sche.endTime) sche.startTime = sche.endTime = -1;
|
|
var startDate = schedule.str("startDate");
|
|
if(startDate!=null) sche.startDate = LocalDate.parse(startDate).toEpochDay() * 86400000L;
|
|
var endDate = schedule.str("endDate");
|
|
if(endDate!=null) sche.endDate = (LocalDate.parse(endDate).toEpochDay() + 1) * 86400000L;
|
|
if(sche.startDate==sche.endDate) sche.startDate = sche.endDate = -1;
|
|
JSList<Integer> weekFilter = schedule.jslist("weekFilter");
|
|
if(weekFilter!=null && ! weekFilter.isEmpty() && weekFilter.size() < 7) sche.weeks = weekFilter;
|
|
if(sches==null) sches = new ArrayList<>();
|
|
sches.add(sche);
|
|
}
|
|
}
|
|
}
|
|
} |