236 lines
15 KiB
Java
236 lines
15 KiB
Java
![]() |
package com.xixun.xixunplayer;
|
||
|
|
||
|
import static android.view.View.VISIBLE;
|
||
|
|
||
|
import android.app.ActivityManager;
|
||
|
import android.graphics.BitmapFactory;
|
||
|
import android.os.Environment;
|
||
|
import android.os.StatFs;
|
||
|
import android.webkit.WebView;
|
||
|
|
||
|
import androidx.annotation.OptIn;
|
||
|
import androidx.media3.common.util.UnstableApi;
|
||
|
|
||
|
import java.io.ByteArrayOutputStream;
|
||
|
import java.io.File;
|
||
|
import java.io.FileInputStream;
|
||
|
import java.io.FileOutputStream;
|
||
|
import java.io.FileReader;
|
||
|
import java.io.InputStream;
|
||
|
import java.io.OutputStream;
|
||
|
import java.io.OutputStreamWriter;
|
||
|
import java.net.Socket;
|
||
|
import java.text.SimpleDateFormat;
|
||
|
import java.util.Arrays;
|
||
|
import java.util.HashSet;
|
||
|
import java.util.concurrent.CountDownLatch;
|
||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||
|
|
||
|
import gnph.util.IOs;
|
||
|
import gnph.util.JSList;
|
||
|
import gnph.util.JSMap;
|
||
|
import gnph.util.NumFmts;
|
||
|
import gnph.util.O;
|
||
|
|
||
|
public class SocketThread extends Thread {
|
||
|
MainActivity main;
|
||
|
Socket socket;
|
||
|
InputStream in;
|
||
|
OutputStream out;
|
||
|
public SocketThread(MainActivity main, Socket socket) {
|
||
|
this.main = main;
|
||
|
this.socket = socket;
|
||
|
}
|
||
|
@OptIn(markerClass = UnstableApi.class) @Override
|
||
|
public void run() {
|
||
|
try {
|
||
|
socket.setSoTimeout(600000);
|
||
|
Util.socketThreads.add(this);
|
||
|
in = socket.getInputStream();
|
||
|
out = socket.getOutputStream();
|
||
|
HashSet<String> hases = null;
|
||
|
ByteArrayOutputStream progJson = null;
|
||
|
while(true) {
|
||
|
var obj = JSMap.from(in);
|
||
|
var _type = obj.stnn("_type");
|
||
|
Util.println("_type: "+_type);
|
||
|
if("consult".equals(_type)) {
|
||
|
JSList<String> ids = obj.jslist("idList");
|
||
|
hases = new HashSet<>();
|
||
|
if(ids!=null) for(int i=0; i<ids.size(); i++) {
|
||
|
if(new File(Util.programDir + "/" + ids.get(i)).exists()) ids.remove(i--);
|
||
|
else hases.add(ids.get(i));
|
||
|
}
|
||
|
new JSMap("_type", _type, "idList", ids).write(out);
|
||
|
} else if("proStart".equals(_type)) {
|
||
|
Util.deleteFiles(obj.intg("proSize"), hases);
|
||
|
} else if("fileStart".equals(_type)) {
|
||
|
var size = obj.intg("size");
|
||
|
var name = obj.stnn("id");
|
||
|
Util.println(" size: " + size + " name: " + name);
|
||
|
if(name.equals("program")) {
|
||
|
progJson = new ByteArrayOutputStream();
|
||
|
IOs.writeCloseOut(progJson, in, size);
|
||
|
} else {
|
||
|
var fOut = new FileOutputStream(Util.programDir + "/" + name);
|
||
|
IOs.write(fOut, in, size);
|
||
|
fOut.flush();
|
||
|
fOut.getFD().sync();
|
||
|
fOut.close();
|
||
|
}
|
||
|
} else if("imgFileStart".equals(_type)) {
|
||
|
var size = obj.intg("size");
|
||
|
var fout = new FileOutputStream(Util.backImgFile);
|
||
|
IOs.write(fout, in, size);
|
||
|
fout.flush();
|
||
|
fout.getFD().sync();
|
||
|
fout.close();
|
||
|
main.runOnUiThread(() -> {
|
||
|
main.backView.cosImg = BitmapFactory.decodeFile(Util.backImgFile);
|
||
|
main.backView.invalidate();
|
||
|
});
|
||
|
} else if("imgFileEnd".equals(_type)) {
|
||
|
new JSMap("success", true).write(out);
|
||
|
} else if("proEnd".equals(_type)) {
|
||
|
new JSMap("success", progJson!=null).write(out);
|
||
|
if(progJson!=null) {
|
||
|
var json = progJson.toByteArray();
|
||
|
progJson = null;
|
||
|
main.runOnUiThread(() -> main.initProg(json));
|
||
|
}
|
||
|
} else if("DelPrograms".equals(_type)) {
|
||
|
var latch = new CountDownLatch(1);
|
||
|
var ok = new AtomicBoolean(false);
|
||
|
main.runOnUiThread(() -> {
|
||
|
ok.set(main.delProgFile());
|
||
|
latch.countDown();
|
||
|
});
|
||
|
try {
|
||
|
latch.await();
|
||
|
} catch (InterruptedException ignored) {}
|
||
|
new JSMap("success", ok.get()).write(out);
|
||
|
} else if("DelBackImg".equals(_type)) {
|
||
|
MainActivity.ins.runOnUiThread(() -> {
|
||
|
MainActivity.ins.backView.cosImg = null;
|
||
|
MainActivity.ins.backView.invalidate();
|
||
|
});
|
||
|
new JSMap("success", new File(Util.backImgFile).delete()).write(out);
|
||
|
} else if("getPlayerState".equals(_type)) {
|
||
|
var descs = Util.getState(main.state);
|
||
|
new JSMap(
|
||
|
"code", main.state,
|
||
|
"des_en", descs[0],
|
||
|
"des", descs[1]
|
||
|
).write(out);
|
||
|
} else if("GetInfo".equals(_type)) {
|
||
|
var writer = new OutputStreamWriter(out);
|
||
|
var Fmt = new SimpleDateFormat("yy-MM-dd HH:mm:ss.SSS");
|
||
|
var dur = 0;
|
||
|
if(main.progView!=null) for(var page : main.progView.pages) dur += page.tDur;
|
||
|
writer.append("ProgSend: ").append(Fmt.format(new File(Util.programDir + "/program").lastModified())).append(" ProgDur: ").append(String.valueOf(dur));
|
||
|
if(main.progView!=null) writer.append(" Pages: ").append(String.valueOf(main.progView.avas.size())).append(" / ").append(String.valueOf(main.progView.pages.size()));
|
||
|
writer.append("\n");
|
||
|
writer.append(" Launch: ").append(Fmt.format(main.launchMilli)).append("\n");
|
||
|
writer.append(" Sync: ").append(Fmt.format(main.syncMs)).append("\n");
|
||
|
if(main.progView==null) writer.append(" ProgView is Null\n");
|
||
|
else if(main.progView.avas.isEmpty()) writer.append(" No Avas\n");
|
||
|
else writer.append("Page End: ").append(Fmt.format(main.progView.curAva().endMilli)).append(" CurPage: ").append(String.valueOf(main.progView.curAva)).append(" / ").append(String.valueOf(main.progView.avas.get(main.progView.curAva))).append("\n");
|
||
|
writer.append(" Current: ").append(Fmt.format(System.currentTimeMillis())).append("\n");
|
||
|
var statFs = new StatFs(Environment.getExternalStorageDirectory().getPath());
|
||
|
writer.append(" Disk: ").append(String.valueOf(statFs.getTotalBytes()/1000000)).append(" ").append(String.valueOf(statFs.getAvailableBytes()/1000000)).append(" ").append(String.valueOf(statFs.getFreeBytes()/1000000)).append(" (total avail free)\n");
|
||
|
var actManager = (ActivityManager) main.getSystemService(main.ACTIVITY_SERVICE);
|
||
|
var memoryInfo = new ActivityManager.MemoryInfo();
|
||
|
actManager.getMemoryInfo(memoryInfo);
|
||
|
writer.append(" Memory: ").append(String.valueOf(memoryInfo.totalMem/1000000)).append(" ").append(String.valueOf(memoryInfo.availMem/1000000)).append(" ").append(String.valueOf(memoryInfo.threshold/1000000)).append(" ").append(String.valueOf(memoryInfo.lowMemory)).append(" (total avail threshold low)\n");
|
||
|
var runtime = Runtime.getRuntime();
|
||
|
writer.append("Runtime: ").append(String.valueOf(runtime.maxMemory()/1000000)).append(" ").append(String.valueOf(runtime.totalMemory()/1000000)).append(" ").append(NumFmts.cfix2().format(runtime.freeMemory()*0.000001)).append(" (max total free)\n");
|
||
|
// writer.append("/proc/stat\n");
|
||
|
// IOs.writeCloseIn(writer, new FileReader("/proc/stat"));
|
||
|
writer.append("\nSockets ").append(String.valueOf(Util.socketThreads.size())).append("\n");
|
||
|
for(var socket : Util.socketThreads) writer.append(" ").append(String.valueOf(socket.socket.getInetAddress())).append(":").append(String.valueOf(socket.socket.getPort())).append(" Buf:").append(String.valueOf(socket.socket.getReceiveBufferSize()/1000)).append("k SoLinger:").append(String.valueOf(socket.socket.getSoLinger())).append("\n");
|
||
|
|
||
|
writer.append("\n");
|
||
|
var latch = new CountDownLatch(1);
|
||
|
main.runOnUiThread(() -> {
|
||
|
if(main.progView!=null && ! main.progView.avas.isEmpty()) {
|
||
|
var page = main.progView.curAva();
|
||
|
for(var layer : page.layers) for(var src : layer.srcs) if(src.view.getVisibility()==VISIBLE) {
|
||
|
try {
|
||
|
if(src.view instanceof SrcVideo) {
|
||
|
var view = (SrcVideo) src.view;
|
||
|
if(view.ijkPlayer!=null) {
|
||
|
writer.append("VideoPlaying: ").append(String.valueOf(view.ijkPlayer.isPlaying())).append("\tCur/Dur: ").append(String.valueOf(view.ijkPlayer.getCurrentPosition())).append("/").append(String.valueOf(view.ijkPlayer.getDuration())).append("\n");
|
||
|
var mediaInfo = view.ijkPlayer.getMediaInfo();
|
||
|
var vStream = mediaInfo.mMeta.mVideoStream;
|
||
|
writer.append(" BitRate: ").append(String.valueOf(view.ijkPlayer.getBitRate()/1000)).append("k\tFPS: ").append(String.valueOf(vStream.mFpsNum/(float)vStream.mFpsDen)).append(" (").append(String.valueOf(vStream.mFpsNum)).append("/").append(String.valueOf(vStream.mFpsDen)).append(")\n");
|
||
|
var tracks = view.ijkPlayer.getTrackInfo();
|
||
|
for(var track : tracks) writer.append(" ").append(track.getInfoInline()).append("\n");
|
||
|
writer.append(" Format: ").append(mediaInfo.mMeta.mFormat).append("\n");
|
||
|
writer.append("VideoDecoder: ").append(mediaInfo.mVideoDecoder).append(" ").append(mediaInfo.mVideoDecoderImpl).append(" (").append(String.valueOf(view.ijkPlayer.getVideoDecoder())).append(")\n");
|
||
|
writer.append("AudioDecoder: ").append(mediaInfo.mAudioDecoder).append(" ").append(mediaInfo.mAudioDecoderImpl).append("\n");
|
||
|
//writer.append("PROFILE: ").append(mediaInfo.mMeta.getString(IjkMediaMeta.IJKM_KEY_CODEC_PROFILE)).append("\n");
|
||
|
} else if(view.exoPlayer!=null) {
|
||
|
writer.append("VideoPlaying: ").append(String.valueOf(view.exoPlayer.isPlaying())).append(" ").append(String.valueOf(view.exoPlayer.getCurrentPosition())).append("/").append(String.valueOf(view.exoPlayer.getDuration())).append("\n");
|
||
|
writer.append(" BitRate: ").append(String.valueOf(view.bitRate/1000)).append("k\n");
|
||
|
writer.append("PlaybackStat: ").append(view.getState()).append("\n");
|
||
|
writer.append(" PlayerError: ").append(String.valueOf(view.exoPlayer.getPlayerError())).append("\n");
|
||
|
writer.append(" VideoFormat: ").append(String.valueOf(view.exoPlayer.getVideoFormat())).append("\n");
|
||
|
var cnt = view.exoPlayer.getRendererCount();
|
||
|
for(int rr=0; rr<cnt; rr++) writer.append(" Renderer: ").append(String.valueOf(view.exoPlayer.getRendererType(rr))).append(" ").append(String.valueOf(view.exoPlayer.getRenderer(rr))).append("\n");
|
||
|
writer.append("getPlaybackParameters: ").append(String.valueOf(view.exoPlayer.getPlaybackParameters())).append("\n");
|
||
|
}
|
||
|
writer.append("\n");
|
||
|
} else if(src.view instanceof SrcWeather) {
|
||
|
var view = (SrcWeather) src.view;
|
||
|
writer.append("SrcWeather html: ").append(view.html).append("\n");
|
||
|
} else if(src.view instanceof WebView) {
|
||
|
var view = (WebView) src.view;
|
||
|
writer.append("Title: ").append(view.getTitle()).append("\n");
|
||
|
writer.append(" Url: ").append(view.getUrl()).append("\n");
|
||
|
writer.append("OrUrl: ").append(view.getOriginalUrl()).append("\n");
|
||
|
writer.append("Progress: ").append(String.valueOf(view.getProgress())).append("\n");
|
||
|
}
|
||
|
} catch (Exception ignored) {
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
latch.countDown();
|
||
|
});
|
||
|
try {
|
||
|
latch.await();
|
||
|
} catch (InterruptedException ignored) {}
|
||
|
writer.flush();
|
||
|
} else if("GetLog".equals(_type)) {
|
||
|
out.write(Util.buf.toString().getBytes());
|
||
|
} else if("ListProgFiles".equals(_type)) {
|
||
|
var files = new File(Util.programDir).listFiles();
|
||
|
if(files == null) return;
|
||
|
Arrays.sort(files, (f1, f2) -> (int) (f2.lastModified() - f1.lastModified()));
|
||
|
var writer = new OutputStreamWriter(out);
|
||
|
for(var file : files) writer.append(file.getName()).append(' ').append(String.valueOf(file.length())).append('\n');
|
||
|
writer.append('\n');
|
||
|
writer.flush();
|
||
|
} else if("GetFile".equals(_type)) {
|
||
|
var name = obj.str("name");
|
||
|
if(name!=null) IOs.writeCloseIn(out, new FileInputStream(Util.programDir+"/"+name));
|
||
|
else new JSMap("code", 1, "msg", "name is null").write(out);
|
||
|
}
|
||
|
out.flush();
|
||
|
Util.println("cmd end");
|
||
|
}
|
||
|
} catch (Throwable e) {
|
||
|
var emsg = e.getMessage();
|
||
|
if(emsg!=null && ("Socket closed".equals(emsg) || emsg.endsWith("end-of-input"))) {
|
||
|
Util.println(emsg);
|
||
|
return;
|
||
|
}
|
||
|
main.runOnUiThread(() -> Util.makeText(main, Util.toStr(e)).show());
|
||
|
Util.printStackTrace(e);
|
||
|
} finally {
|
||
|
Util.socketThreads.remove(this);
|
||
|
O.close(in, out, socket);
|
||
|
Util.println("conn end\n");
|
||
|
}
|
||
|
}
|
||
|
}
|