[*] 日常优化

This commit is contained in:
acgist
2023-06-16 08:46:08 +08:00
parent 86f4a5fea9
commit 2726a9487e
6 changed files with 155 additions and 43 deletions

View File

@@ -620,7 +620,9 @@ public final class Taoyao implements ITaoyao {
* @param message 信令消息 * @param message 信令消息
*/ */
private void dispatch(final String content, final Header header, final Message message) { private void dispatch(final String content, final Header header, final Message message) {
if(this.taoyaoListener.preOnMessage(message)) { final boolean done = this.taoyaoListener.preOnMessage(message);
if(done) {
Log.d(Taoyao.class.getSimpleName(), "信令前置处理完成:" + message);
return; return;
} }
switch (header.getSignal()) { switch (header.getSignal()) {

View File

@@ -15,52 +15,59 @@ import java.util.function.Function;
public interface ITaoyao { public interface ITaoyao {
/** /**
* @param signal 信令 * @param signal 信令标识
* @param args 消息主体内容 * @param args 消息主体
* *
* @return 消息 * @return 信令消息
*/ */
Message buildMessage(String signal, Object ... args); Message buildMessage(String signal, Object ... args);
/** /**
* @param signal 信令 * @param signal 信令标识
* @param body 消息主体 * @param body 消息主体
* *
* @return 消息 * @return 信令消息
*/ */
Message buildMessage(String signal, Object body); Message buildMessage(String signal, Object body);
/** /**
* 推送信令消息
*
* @param message 信令消息 * @param message 信令消息
*/ */
void push(Message message); void push(Message message);
/** /**
* @param request 信令请求消息 * 请求信令消息
* *
* @return 信令响应消息 * @param request 请求信令消息
*
* @return 响应信令消息
*/ */
Message request(Message request); Message request(Message request);
/** /**
* @param request 信令请求消息 * 请求信令消息
* @param success 成功
* *
* @return 结果 * @param request 请求信令消息
* @param success 成功请求执行
*
* @return 执行结果
*/ */
default <T> T requestFuture(Message request, Function<Message, T> success) { default <T> T requestFuture(Message request, Function<Message, T> success) {
return this.requestFuture(request, success, null); return this.requestFuture(request, success, null);
} }
/** /**
* @param request 信令请求消息 * 请求信令消息
* @param success 成功
* @param failure 失败
* *
* @return 结果 * @param request 请求信令消息
* @param success 成功请求执行
* @param failure 失败请求执行
*
* @return 执行结果
*/ */
default <T> T requestFuture(Message request, Function<Message, T> success, Function<Message, T> failure) { default <T> T requestFuture(Message request, Function<Message, T> success, Function<Message, T> failure) {
// final CompletableFuture<Message> completableFuture = new CompletableFuture<>();
final Message response = this.request(request); final Message response = this.request(request);
if(response != null && response.isSuccess()) { if(response != null && response.isSuccess()) {
return success.apply(response); return success.apply(response);
@@ -74,20 +81,23 @@ public interface ITaoyao {
} }
/** /**
* @param request 信令请求消息 * 请求信令消息
* @param success 成功 *
* @param request 请求信令消息
* @param success 成功请求执行
*/ */
default void requestFuture(Message request, Consumer<Message> success) { default void requestFuture(Message request, Consumer<Message> success) {
this.requestFuture(request, success, null); this.requestFuture(request, success, null);
} }
/** /**
* 请求信令消息
*
* @param request 信令请求消息 * @param request 信令请求消息
* @param success 成功 * @param success 成功请求执行
* @param failure 失败 * @param failure 失败请求执行
*/ */
default void requestFuture(Message request, Consumer<Message> success, Consumer<Message> failure) { default void requestFuture(Message request, Consumer<Message> success, Consumer<Message> failure) {
// final CompletableFuture<Message> completableFuture = new CompletableFuture<>();
final Message response = this.request(request); final Message response = this.request(request);
if(response != null && response.isSuccess()) { if(response != null && response.isSuccess()) {
success.accept(response); success.accept(response);

View File

@@ -14,7 +14,7 @@ public interface ITaoyaoListener {
* *
* @param message 信令消息 * @param message 信令消息
* *
* @return 是否继续处理信令 * @return 是否完成
*/ */
default boolean preOnMessage(Message message) { default boolean preOnMessage(Message message) {
return false; return false;

View File

@@ -11,6 +11,10 @@ import org.webrtc.VideoFrame;
*/ */
public class AiProcesser extends VideoProcesser { public class AiProcesser extends VideoProcesser {
public AiProcesser() {
super("AI识别处理器");
}
@Override @Override
protected void doProcess(VideoFrame.I420Buffer i420Buffer) { protected void doProcess(VideoFrame.I420Buffer i420Buffer) {
} }

View File

@@ -1,16 +1,36 @@
package com.acgist.taoyao.media.video; package com.acgist.taoyao.media.video;
import android.util.Log;
import org.webrtc.VideoFrame; import org.webrtc.VideoFrame;
import java.io.Closeable; import java.io.Closeable;
/** /**
* 视频处理器 * 视频处理器
*
* @author acgist
*/ */
public abstract class VideoProcesser implements Closeable { public abstract class VideoProcesser implements Closeable {
/**
* 处理器名称
*/
protected final String name;
/**
* 下一个视频处理器
*/
protected VideoProcesser next; protected VideoProcesser next;
public VideoProcesser(String name) {
this.name = name;
}
/**
* 处理视频帧
*
* @param i420Buffer 视频帧
*/
public void process(VideoFrame.I420Buffer i420Buffer) { public void process(VideoFrame.I420Buffer i420Buffer) {
this.doProcess(i420Buffer); this.doProcess(i420Buffer);
if(this.next == null) { if(this.next == null) {
@@ -20,9 +40,18 @@ public abstract class VideoProcesser implements Closeable {
} }
} }
/**
* 处理视频帧
*
* @param i420Buffer 视频帧
*/
protected abstract void doProcess(VideoFrame.I420Buffer i420Buffer); protected abstract void doProcess(VideoFrame.I420Buffer i420Buffer);
/**
* 关闭处理器
*/
public void close() { public void close() {
Log.i(VideoProcesser.class.getSimpleName(), "关闭视频处理器:" + this.name);
if(this.next == null) { if(this.next == null) {
// 忽略 // 忽略
} else { } else {

View File

@@ -29,40 +29,84 @@ import java.util.TimerTask;
*/ */
public class WatermarkProcesser extends VideoProcesser { public class WatermarkProcesser extends VideoProcesser {
/**
* 字符矩阵
*/
private static final WatermarkMatrix[] MATRICES = new WatermarkMatrix[256]; private static final WatermarkMatrix[] MATRICES = new WatermarkMatrix[256];
/**
* 水印字符
*/
private static final String WATERMARK = "-: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
/**
* 时间格式
*/
private final String format; private final String format;
/**
* 格式
*/
private final DateTimeFormatter formatter;
/**
* 视频宽度
*/
private final int width; private final int width;
/**
* 视频高度
*/
private final int height; private final int height;
/**
* 定时器
*/
private final Timer timer; private final Timer timer;
/**
* 字符矩阵
*/
private final WatermarkMatrix[] watermark; private final WatermarkMatrix[] watermark;
static {
final char[] chars = WATERMARK.toCharArray();
for (char value : chars) {
WatermarkProcesser.build(value);
}
}
/**
* @param format 时间格式
* @param width 视频宽度
* @param height 视频高度
*/
public WatermarkProcesser(String format, int width, int height) { public WatermarkProcesser(String format, int width, int height) {
super("水印处理器");
this.format = format; this.format = format;
this.width = width; this.width = width;
this.height = height; this.height = height;
final String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern(format)); this.formatter = DateTimeFormatter.ofPattern(format);
this.watermark = new WatermarkMatrix[date.length()]; final String date = LocalDateTime.now().format(this.formatter);
this.timer = new Timer("Watermark-Timer", true); this.watermark = new WatermarkMatrix[date.length()];
this.timer = new Timer("Watermark-Timer", true);
this.init(); this.init();
} }
/**
* @param format 时间格式
* @param width 视频宽度
* @param height 视频高度
* @param videoProcesser 下个视频处理器
*/
public WatermarkProcesser(String format, int width, int height, VideoProcesser videoProcesser) { public WatermarkProcesser(String format, int width, int height, VideoProcesser videoProcesser) {
this(format, width, height); this(format, width, height);
this.next = videoProcesser; this.next = videoProcesser;
} }
/**
* 加载水印
*/
private void init() { private void init() {
final String source = "-: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
final char[] chars = source.toCharArray();
for (char value : chars) {
this.build(value);
}
this.timer.schedule(new TimerTask() { this.timer.schedule(new TimerTask() {
@Override @Override
public void run() { public void run() {
int index = 0; int index = 0;
final char[] chars = LocalDateTime.now().format(DateTimeFormatter.ofPattern(WatermarkProcesser.this.format)).toCharArray(); final char[] chars = LocalDateTime.now().format(WatermarkProcesser.this.formatter).toCharArray();
for (char value : chars) { for (char value : chars) {
WatermarkProcesser.this.watermark[index] = MATRICES[value]; WatermarkProcesser.this.watermark[index] = MATRICES[value];
index++; index++;
@@ -71,21 +115,25 @@ public class WatermarkProcesser extends VideoProcesser {
}, 1000, 1000); }, 1000, 1000);
} }
private void build(char source) { /**
// TODO优化复用bitmap * 创建字符矩阵
final String target = Character.toString(source); *
* @param source 字符
*/
private static void build(char source) {
final Paint paint = new Paint(); final Paint paint = new Paint();
paint.setColor(Color.WHITE); paint.setColor(Color.WHITE);
paint.setDither(true); paint.setDither(true);
paint.setTextSize(40.0F); paint.setTextSize(40.0F);
paint.setTextAlign(Paint.Align.LEFT); paint.setTextAlign(Paint.Align.LEFT);
paint.setFilterBitmap(true); paint.setFilterBitmap(true);
final Paint.FontMetricsInt box = paint.getFontMetricsInt(); final Paint.FontMetricsInt fontMetricsInt = paint.getFontMetricsInt();
final int width = (int) paint.measureText(target); final String target = Character.toString(source);
final int height = box.descent - box.ascent; final int width = (int) paint.measureText(target);
final int height = fontMetricsInt.descent - fontMetricsInt.ascent;
final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap); final Canvas canvas = new Canvas(bitmap);
canvas.drawText(target, 0, box.leading - box.ascent, paint); canvas.drawText(target, 0, fontMetricsInt.leading - fontMetricsInt.ascent, paint);
canvas.save(); canvas.save();
final boolean[][] matrix = new boolean[width][height]; final boolean[][] matrix = new boolean[width][height];
for (int j = 0; j < height; j++) { for (int j = 0; j < height; j++) {
@@ -97,16 +145,16 @@ public class WatermarkProcesser extends VideoProcesser {
} }
} }
} }
MATRICES[source] = new WatermarkMatrix(width, height, matrix);
bitmap.recycle(); bitmap.recycle();
WatermarkProcesser.MATRICES[source] = new WatermarkMatrix(width, height, matrix);
} }
@Override @Override
protected void doProcess(VideoFrame.I420Buffer i420Buffer) { protected void doProcess(VideoFrame.I420Buffer i420Buffer) {
int widthPos = 0; int widthPos = 0;
int heightPos = 0; int heightPos = 0;
final ByteBuffer buffer = i420Buffer.getDataY(); final ByteBuffer buffer = i420Buffer.getDataY();
for (WatermarkMatrix matrix : watermark) { for (WatermarkMatrix matrix : this.watermark) {
if(matrix == null) { if(matrix == null) {
continue; continue;
} }
@@ -117,7 +165,7 @@ public class WatermarkProcesser extends VideoProcesser {
} }
} }
} }
widthPos += matrix.width; widthPos += matrix.width;
heightPos += matrix.height; heightPos += matrix.height;
} }
} }
@@ -128,12 +176,31 @@ public class WatermarkProcesser extends VideoProcesser {
this.timer.cancel(); this.timer.cancel();
} }
/**
* 水印矩阵
*
* @author acgist
*/
static class WatermarkMatrix { static class WatermarkMatrix {
/**
* 字符宽度
*/
int width; int width;
/**
* 字符高度
*/
int height; int height;
/**
* 字符矩阵
*/
boolean[][] matrix; boolean[][] matrix;
/**
* @param width 字符宽度
* @param height 字符高度
* @param matrix 字符矩阵
*/
public WatermarkMatrix(int width, int height, boolean[][] matrix) { public WatermarkMatrix(int width, int height, boolean[][] matrix) {
this.width = width; this.width = width;
this.height = height; this.height = height;