xixunplayer

This commit is contained in:
Gangphon 2023-11-10 20:44:11 +08:00
parent 9b9141ddf7
commit 45c88743d6
9 changed files with 225 additions and 66 deletions

View File

@ -0,0 +1,107 @@
package com.xixun.xixunplayer;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
public class AbsLayout extends ViewGroup {
public AbsLayout(Context context) {
this(context, null);
}
public AbsLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AbsLayout(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public AbsLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int count = getChildCount();
int maxHeight = 0;
int maxWidth = 0;
measureChildren(widthMeasureSpec, heightMeasureSpec);
for(int i = 0; i < count; i++) {
View child = getChildAt(i);
if(child.getVisibility() != GONE) {
int childRight;
int childBottom;
var lp = (LayoutParams) child.getLayoutParams();
childRight = lp.x + child.getMeasuredWidth();
childBottom = lp.y + child.getMeasuredHeight();
maxWidth = Math.max(maxWidth, childRight);
maxHeight = Math.max(maxHeight, childBottom);
}
}
maxWidth += getPaddingLeft() + getPaddingRight();
maxHeight += getPaddingTop() + getPaddingBottom();
maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0), resolveSizeAndState(maxHeight, heightMeasureSpec, 0));
}
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(0, 0, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if(child.getVisibility() != GONE) {
var lp = (LayoutParams) child.getLayoutParams();
int childLeft = getPaddingLeft() + lp.x;
int childTop = getPaddingTop() + lp.y;
child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight());
}
}
}
@Override
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(p);
}
@Override
public boolean shouldDelayChildPressedState() {
return false;
}
public static class LayoutParams extends ViewGroup.LayoutParams {
public int x;
public int y;
public LayoutParams(int x, int y, int width, int height) {
super(width, height);
this.x = x;
this.y = y;
}
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
}
}
}

View File

@ -0,0 +1,7 @@
package com.xixun.xixunplayer;
import android.graphics.Canvas;
public interface DrawOther {
void drawOther(Canvas canvas);
}

View File

@ -14,9 +14,10 @@ import java.util.Random;
import gnph.util.JSList; import gnph.util.JSList;
import gnph.util.JSMap; import gnph.util.JSMap;
public class EleFlip extends View implements Choreographer.FrameCallback { public class EleFlip extends View implements DrawOther, Choreographer.FrameCallback {
static final char effTypes[] = {'l', 't', 'r', 'b'}; static final char effTypes[] = {'l', 't', 'r', 'b'};
ArrayList<EleOtherPart> others;
Random rand = new Random(); Random rand = new Random();
ArrayList<Bitmap> imgs = new ArrayList<>(); ArrayList<Bitmap> imgs = new ArrayList<>();
int picDur, EffDur, AniInterval, step, imgc, imgx, imgy; int picDur, EffDur, AniInterval, step, imgc, imgx, imgy;
@ -73,6 +74,10 @@ public class EleFlip extends View implements Choreographer.FrameCallback {
startMove(); startMove();
choreographer.postFrameCallback(this); choreographer.postFrameCallback(this);
} }
drawOther(canvas);
}
@Override
public void drawOther(Canvas canvas) {
canvas.drawBitmap(imgs.get(imgc), imgx, imgy, null); canvas.drawBitmap(imgs.get(imgc), imgx, imgy, null);
} }
@ -106,6 +111,7 @@ public class EleFlip extends View implements Choreographer.FrameCallback {
} }
if(imgx==0 && imgy==0) AniInterval = 0; if(imgx==0 && imgy==0) AniInterval = 0;
invalidate(); invalidate();
if(others!=null) for(var other : others) other.invalidate();
} }
} }
} else { } else {
@ -115,6 +121,7 @@ public class EleFlip extends View implements Choreographer.FrameCallback {
else imgc++; else imgc++;
startMove(); startMove();
invalidate(); invalidate();
if(others!=null) for(var other : others) other.invalidate();
} }
choreographer.postFrameCallback(this); choreographer.postFrameCallback(this);
} }

View File

@ -0,0 +1,26 @@
package com.xixun.xixunplayer;
import android.content.Context;
import android.graphics.Canvas;
import android.view.View;
public class EleOtherPart extends View {
DrawOther master;
public EleOtherPart(Context context, DrawOther master) {
super(context);
this.master = master;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
try {
master.drawOther(canvas);
} catch (Throwable e) {
setVisibility(GONE);
e.printStackTrace();
}
}
}

View File

@ -8,10 +8,13 @@ import android.view.Choreographer;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import java.util.ArrayList;
import gnph.util.JSMap; import gnph.util.JSMap;
public class EleScroll extends View implements Choreographer.FrameCallback { public class EleScroll extends View implements DrawOther, Choreographer.FrameCallback {
ArrayList<EleOtherPart> others;
Bitmap img; Bitmap img;
int interval, cur, end, step; int interval, cur, end, step;
char effect; char effect;
@ -44,12 +47,24 @@ public class EleScroll extends View implements Choreographer.FrameCallback {
super.onDraw(canvas); super.onDraw(canvas);
if(img==null) return; if(img==null) return;
try { try {
drawOther(canvas);
if(freshCnt==0 && effect!=0 && interval!=0) choreographer.postFrameCallback(this);
} catch (Throwable e) {
setVisibility(GONE);
img = null;
e.printStackTrace();
}
}
@Override
public void drawOther(Canvas canvas) {
if(img==null) return;
if(effect=='l') { if(effect=='l') {
canvas.drawBitmap(img, cur, 0, null); canvas.drawBitmap(img, cur, 0, null);
canvas.drawBitmap(img, cur+img.getWidth(), 0, null); canvas.drawBitmap(img, cur+img.getWidth(), 0, null);
} else if(effect=='r') { } else if(effect=='r') {
canvas.drawBitmap(img, cur, 0, null); var x = cur-img.getWidth()+getWidth();
canvas.drawBitmap(img, cur-img.getWidth(), 0, null); canvas.drawBitmap(img, x, 0, null);
canvas.drawBitmap(img, x-img.getWidth(), 0, null);
} else if(effect=='t') { } else if(effect=='t') {
canvas.drawBitmap(img, 0, cur, null); canvas.drawBitmap(img, 0, cur, null);
canvas.drawBitmap(img, 0, cur+img.getHeight(), null); canvas.drawBitmap(img, 0, cur+img.getHeight(), null);
@ -57,12 +72,6 @@ public class EleScroll extends View implements Choreographer.FrameCallback {
canvas.drawBitmap(img, 0, cur, null); canvas.drawBitmap(img, 0, cur, null);
canvas.drawBitmap(img, 0, cur-img.getHeight(), null); canvas.drawBitmap(img, 0, cur-img.getHeight(), null);
} else canvas.drawBitmap(img, 0, 0, null); } else canvas.drawBitmap(img, 0, 0, null);
if(freshCnt==0 && effect!=0 && interval!=0) choreographer.postFrameCallback(this);
} catch (Throwable e) {
setVisibility(GONE);
img = null;
e.printStackTrace();
}
} }
Choreographer choreographer = Choreographer.getInstance(); Choreographer choreographer = Choreographer.getInstance();
@ -85,6 +94,7 @@ public class EleScroll extends View implements Choreographer.FrameCallback {
else cur += step; else cur += step;
} }
invalidate(); invalidate();
if(others!=null) for(var other : others) other.invalidate();
} }
choreographer.postFrameCallback(this); choreographer.postFrameCallback(this);
} }

View File

@ -42,15 +42,20 @@ public class EleVideo extends VideoView implements Choreographer.FrameCallback {
} else { } else {
seekTo(0); seekTo(0);
pause(); pause();
showCnt = 5;
choreographer.postFrameCallback(this); choreographer.postFrameCallback(this);
} }
} }
Choreographer choreographer = Choreographer.getInstance(); Choreographer choreographer = Choreographer.getInstance();
int showCnt;
@Override @Override
public void doFrame(long frameTimeNanos) { public void doFrame(long frameTimeNanos) {
if(isShown()) return; if(isShown()) {
if(isPlaying()) { seekTo(0);
if(showCnt>0) showCnt--;
else return;
} else if(isPlaying()) {
seekTo(0); seekTo(0);
pause(); pause();
System.out.println("pause in doFrame()"); System.out.println("pause in doFrame()");

View File

@ -306,7 +306,7 @@ public class MainActivity extends ComponentActivity implements Choreographer.Fra
state = 3; state = 3;
return; return;
} }
var view = new ProgView(task, backView.width, backView.height, this); var view = new ProgView(task, this);
if(view.getChildCount()==0) { if(view.getChildCount()==0) {
state = 3; state = 3;
return; return;
@ -384,7 +384,7 @@ public class MainActivity extends ComponentActivity implements Choreographer.Fra
} else { } else {
var page = page(curAva = 0); var page = page(curAva = 0);
syncMilli = milli / dur * dur + dur; syncMilli = milli / dur * dur + dur;
if(syncMilli - milli >= 2000) page.setMillis(milli); if(syncMilli - milli >= 500) page.setMillis(milli);
if(state != 6) { if(state != 6) {
setContentView(progView); setContentView(progView);
state = 6; state = 6;

View File

@ -21,7 +21,6 @@ public class Page {
long endMilli = Long.MAX_VALUE; long endMilli = Long.MAX_VALUE;
int startTime; int startTime;
int endTime; int endTime;
int x;
String id; String id;
String type; String type;
boolean isVideo; boolean isVideo;
@ -29,7 +28,7 @@ public class Page {
void show() { void show() {
if(view.getVisibility()==VISIBLE) return; if(view.getVisibility()==VISIBLE) return;
view.setVisibility(VISIBLE); view.setVisibility(VISIBLE);
if(isVideo) view.setLeft(x); if(isVideo) view.setLeft(0);
} }
void hide() { void hide() {
if(view.getVisibility()!=VISIBLE) return; if(view.getVisibility()!=VISIBLE) return;

View File

@ -1,11 +1,10 @@
package com.xixun.xixunplayer; package com.xixun.xixunplayer;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.webkit.WebView; import android.webkit.WebView;
import android.webkit.WebViewClient; import android.webkit.WebViewClient;
import android.widget.AbsoluteLayout;
import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import java.io.File; import java.io.File;
@ -15,18 +14,19 @@ import gnph.util.JSList;
import gnph.util.JSMap; import gnph.util.JSMap;
import pl.droidsonroids.gif.GifImageView; import pl.droidsonroids.gif.GifImageView;
public class ProgView extends AbsoluteLayout { @SuppressLint("ViewConstructor")
public class ProgView extends AbsLayout {
ArrayList<Page> pages = new ArrayList<>(); ArrayList<Page> pages = new ArrayList<>();
public ProgView(JSMap task, int width, int height, Context context) { public ProgView(JSMap task, Context context) {
super(context); super(context);
JSList<JSMap> jpages = task.jslist("items"); JSList<JSMap> jpages = task.jslist("items");
for(var pageMap : jpages) { for(var pageMap : jpages) {
var _program = pageMap.jsmap("_program"); var _program = pageMap.jsmap("_program");
JSList<JSMap> layers = _program.jslist("layers"); JSList<JSMap> layers = _program.jslist("layers");
if(layers.isEmpty()) continue; if(layers.isEmpty()) continue;
var splitWidths = _program.jslist("splitWidths"); JSList<Long> splitWidths = _program.jslist("splitWidths");
var page = new Page(); var page = new Page();
page.repeatTimes = pageMap.intg("repeatTimes"); page.repeatTimes = pageMap.intg("repeatTimes");
page.parse(pageMap.jslist("schedules")); page.parse(pageMap.jslist("schedules"));
@ -73,43 +73,44 @@ public class ProgView extends AbsoluteLayout {
if(imgs.size()==1 && imgs.get(0).intg("picDuration")==0) ele.view = new EleScroll(Util.programDir+"/", imgs.get(0), context); 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 ele.view = new EleFlip(Util.programDir+"/", imgs, context);
} else if(ele.type.equals("SplitText")) { } else if(ele.type.equals("SplitText")) {
// JSList<JSMap> imgs = source.jslist("arrayPics"); JSList<JSMap> imgs = source.jslist("arrayPics");
// if(imgs.isEmpty()) continue; if(imgs.isEmpty()) continue;
// ele.wgt = new View(context); ele.view = new AbsLayout(context);
// page.addView(ele.wgt, new AbsoluteLayout.LayoutParams(width, height, 0, 0)); var partHeight = _program.intg("height");
// var pheight = _program.intg("height"); if(imgs.size()==1 && imgs.get(0).intg("picDuration")==0) {
// if(imgs.size()==1 && imgs.get(0).intg("picDuration")==0) { var view = new EleScroll(Util.programDir+"/", imgs.get(0), context);
// var wgt = new EleScroll(ele.wgt, dir+"/", imgs.get(0), context); ((AbsLayout) ele.view).addView(view, new AbsLayout.LayoutParams(x, y, splitWidths.get(0).intValue(), h));
// wgt->setGeometry(ele.x, ele.y, ele.w, ele.h); view.others = new ArrayList<>();
// for(int i=1; i<splitWidths.size(); i++) { for(int i=1; i<splitWidths.size(); i++) {
// ele.x -= splitWidths[i-1].toInt(); x -= splitWidths.get(i-1);
// ele.y += height; y += partHeight;
// auto split = new EleSplitScroll(ele.wgt, wgt); var split = new EleOtherPart(context, view);
// split->setGeometry(ele.x, ele.y, splitWidths[i].toInt()-ele.x, ele.h); ((AbsLayout) ele.view).addView(split, new AbsLayout.LayoutParams(x, y, splitWidths.get(i).intValue() - x, h));
// wgt->splits.append(split); view.others.add(split);
// } }
// } else { } else {
// auto wgt = new EleFlip(dir+"/", imgs, ele.wgt); var view = new EleFlip(Util.programDir+"/", imgs, context);
// wgt->setGeometry(ele.x, ele.y, ele.w, ele.h); ((AbsLayout) ele.view).addView(view, new AbsLayout.LayoutParams(x, y, splitWidths.get(0).intValue(), h));
// for(int i=1; i<splitWidths.size(); i++) { view.others = new ArrayList<>();
// ele.x -= splitWidths[i-1].toInt(); for(int i=1; i<splitWidths.size(); i++) {
// ele.y += height; x -= splitWidths.get(i-1);
// auto split = new EleSplitPng(wgt, ele.wgt); y += partHeight;
// split->setGeometry(ele.x, ele.y, splitWidths[i].toInt()-ele.x, ele.h); var split = new EleOtherPart(context, view);
// wgt->splits.append(split); ((AbsLayout) ele.view).addView(split, new AbsLayout.LayoutParams(x, y, splitWidths.get(i).intValue() - x, h));
// } view.others.add(split);
// } }
// ele.w = 0; }
w = 0;
} else if(ele.type.equals("DigitalClockNew")) ele.view = new EleDigiClock(Util.programDir+"/", source, context); } 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+"/"+ele.id, source, context); else if(ele.type.equals("AnalogClock")) ele.view = new EleAnaClock(w, h, Util.programDir+"/"+ele.id, source, context);
else if(ele.type.equals("Video")) { else if(ele.type.equals("Video")) {
ele.isVideo = true; ele.isVideo = true;
var videoView = new EleVideo(Util.programDir + "/" + ele.id, context); var videoView = new EleVideo(Util.programDir + "/" + ele.id, context);
var frame = new FrameLayout(context); ele.view = new AbsLayout(context);
frame.addView(videoView); ((AbsLayout) ele.view).addView(videoView, new AbsLayout.LayoutParams(x, y, w, h));
ele.view = frame;
var vol = source.intg("vol", 100); var vol = source.intg("vol", 100);
if(vol < 100) videoView.vol = vol / 100.0f; if(vol < 100) videoView.vol = vol / 100.0f;
w = 0;
} else if(ele.type.equals("Audio")) { } else if(ele.type.equals("Audio")) {
var videoView = new EleVideo(Util.programDir+"/"+ele.id, context); var videoView = new EleVideo(Util.programDir+"/"+ele.id, context);
ele.view = videoView; ele.view = videoView;
@ -130,10 +131,9 @@ public class ProgView extends AbsoluteLayout {
else if(ele.type.equals("EnvironmentalMonitoring")) ele.view = new EleEnviron(Util.programDir+"/", source, context); else if(ele.type.equals("EnvironmentalMonitoring")) ele.view = new EleEnviron(Util.programDir+"/", source, context);
else continue; else continue;
if(ele.view==null) continue; if(ele.view==null) continue;
if(w > 0) { if(w > 0) ele.view.setLayoutParams(new AbsLayout.LayoutParams(x, y, w, h));
ele.view.setVisibility(GONE); ele.view.setVisibility(GONE);
addView(ele.view, new AbsoluteLayout.LayoutParams(w, h, x, y)); addView(ele.view);
}
layer.eles.add(ele); layer.eles.add(ele);
ele = new Page.EleBase(); ele = new Page.EleBase();
} }
@ -147,7 +147,7 @@ public class ProgView extends AbsoluteLayout {
ele.endTime = bdEnd; ele.endTime = bdEnd;
ele.view = bdEle; ele.view = bdEle;
ele.view.setVisibility(GONE); ele.view.setVisibility(GONE);
addView(ele.view, new AbsoluteLayout.LayoutParams(w, h, x, y)); addView(ele.view, new AbsLayout.LayoutParams(x, y, w, h));
layer.eles.add(ele); layer.eles.add(ele);
} }
if(! layer.eles.isEmpty()) page.layers.add(layer); if(! layer.eles.isEmpty()) page.layers.add(layer);
@ -158,10 +158,8 @@ public class ProgView extends AbsoluteLayout {
for(int ee=0; ee<layer.eles.size(); ee++) { for(int ee=0; ee<layer.eles.size(); ee++) {
var ele = layer.eles.get(ee); var ele = layer.eles.get(ee);
if(ele.startTime >= page.dur) { if(ele.startTime >= page.dur) {
if(layer.eles.size() > 1) { if(layer.eles.size() > 1) layer.eles.remove(ee--);
layer.eles.remove(ee--); else {
continue;
} else {
page.layers.remove(ll--); page.layers.remove(ll--);
continue for_layer; continue for_layer;
} }