[*] 日常优化
This commit is contained in:
@@ -620,7 +620,9 @@ public final class Taoyao implements ITaoyao {
|
||||
* @param 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;
|
||||
}
|
||||
switch (header.getSignal()) {
|
||||
|
||||
@@ -15,52 +15,59 @@ import java.util.function.Function;
|
||||
public interface ITaoyao {
|
||||
|
||||
/**
|
||||
* @param signal 信令
|
||||
* @param args 消息主体内容
|
||||
* @param signal 信令标识
|
||||
* @param args 消息主体
|
||||
*
|
||||
* @return 消息
|
||||
* @return 信令消息
|
||||
*/
|
||||
Message buildMessage(String signal, Object ... args);
|
||||
|
||||
/**
|
||||
* @param signal 信令
|
||||
* @param signal 信令标识
|
||||
* @param body 消息主体
|
||||
*
|
||||
* @return 消息
|
||||
* @return 信令消息
|
||||
*/
|
||||
Message buildMessage(String signal, Object body);
|
||||
|
||||
/**
|
||||
* 推送信令消息
|
||||
*
|
||||
* @param message 信令消息
|
||||
*/
|
||||
void push(Message message);
|
||||
|
||||
/**
|
||||
* @param request 信令请求消息
|
||||
* 请求信令消息
|
||||
*
|
||||
* @return 信令响应消息
|
||||
* @param request 请求信令消息
|
||||
*
|
||||
* @return 响应信令消息
|
||||
*/
|
||||
Message request(Message request);
|
||||
|
||||
/**
|
||||
* @param request 信令请求消息
|
||||
* @param success 成功
|
||||
* 请求信令消息
|
||||
*
|
||||
* @return 结果
|
||||
* @param request 请求信令消息
|
||||
* @param success 成功请求执行
|
||||
*
|
||||
* @return 执行结果
|
||||
*/
|
||||
default <T> T requestFuture(Message request, Function<Message, T> success) {
|
||||
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) {
|
||||
// final CompletableFuture<Message> completableFuture = new CompletableFuture<>();
|
||||
final Message response = this.request(request);
|
||||
if(response != null && response.isSuccess()) {
|
||||
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) {
|
||||
this.requestFuture(request, success, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求信令消息
|
||||
*
|
||||
* @param request 信令请求消息
|
||||
* @param success 成功
|
||||
* @param failure 失败
|
||||
* @param success 成功请求执行
|
||||
* @param failure 失败请求执行
|
||||
*/
|
||||
default void requestFuture(Message request, Consumer<Message> success, Consumer<Message> failure) {
|
||||
// final CompletableFuture<Message> completableFuture = new CompletableFuture<>();
|
||||
final Message response = this.request(request);
|
||||
if(response != null && response.isSuccess()) {
|
||||
success.accept(response);
|
||||
|
||||
@@ -14,7 +14,7 @@ public interface ITaoyaoListener {
|
||||
*
|
||||
* @param message 信令消息
|
||||
*
|
||||
* @return 是否继续处理信令
|
||||
* @return 是否完成
|
||||
*/
|
||||
default boolean preOnMessage(Message message) {
|
||||
return false;
|
||||
|
||||
@@ -11,6 +11,10 @@ import org.webrtc.VideoFrame;
|
||||
*/
|
||||
public class AiProcesser extends VideoProcesser {
|
||||
|
||||
public AiProcesser() {
|
||||
super("AI识别处理器");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doProcess(VideoFrame.I420Buffer i420Buffer) {
|
||||
}
|
||||
|
||||
@@ -1,16 +1,36 @@
|
||||
package com.acgist.taoyao.media.video;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.webrtc.VideoFrame;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
/**
|
||||
* 视频处理器
|
||||
*
|
||||
* @author acgist
|
||||
*/
|
||||
public abstract class VideoProcesser implements Closeable {
|
||||
|
||||
/**
|
||||
* 处理器名称
|
||||
*/
|
||||
protected final String name;
|
||||
/**
|
||||
* 下一个视频处理器
|
||||
*/
|
||||
protected VideoProcesser next;
|
||||
|
||||
public VideoProcesser(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理视频帧
|
||||
*
|
||||
* @param i420Buffer 视频帧
|
||||
*/
|
||||
public void process(VideoFrame.I420Buffer i420Buffer) {
|
||||
this.doProcess(i420Buffer);
|
||||
if(this.next == null) {
|
||||
@@ -20,9 +40,18 @@ public abstract class VideoProcesser implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理视频帧
|
||||
*
|
||||
* @param i420Buffer 视频帧
|
||||
*/
|
||||
protected abstract void doProcess(VideoFrame.I420Buffer i420Buffer);
|
||||
|
||||
/**
|
||||
* 关闭处理器
|
||||
*/
|
||||
public void close() {
|
||||
Log.i(VideoProcesser.class.getSimpleName(), "关闭视频处理器:" + this.name);
|
||||
if(this.next == null) {
|
||||
// 忽略
|
||||
} else {
|
||||
|
||||
@@ -29,40 +29,84 @@ import java.util.TimerTask;
|
||||
*/
|
||||
public class WatermarkProcesser extends VideoProcesser {
|
||||
|
||||
/**
|
||||
* 字符矩阵
|
||||
*/
|
||||
private static final WatermarkMatrix[] MATRICES = new WatermarkMatrix[256];
|
||||
/**
|
||||
* 水印字符
|
||||
*/
|
||||
private static final String WATERMARK = "-: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
/**
|
||||
* 时间格式
|
||||
*/
|
||||
private final String format;
|
||||
/**
|
||||
* 格式
|
||||
*/
|
||||
private final DateTimeFormatter formatter;
|
||||
/**
|
||||
* 视频宽度
|
||||
*/
|
||||
private final int width;
|
||||
/**
|
||||
* 视频高度
|
||||
*/
|
||||
private final int height;
|
||||
/**
|
||||
* 定时器
|
||||
*/
|
||||
private final Timer timer;
|
||||
/**
|
||||
* 字符矩阵
|
||||
*/
|
||||
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) {
|
||||
super("水印处理器");
|
||||
this.format = format;
|
||||
this.width = width;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
final String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern(format));
|
||||
this.watermark = new WatermarkMatrix[date.length()];
|
||||
this.timer = new Timer("Watermark-Timer", true);
|
||||
this.formatter = DateTimeFormatter.ofPattern(format);
|
||||
final String date = LocalDateTime.now().format(this.formatter);
|
||||
this.watermark = new WatermarkMatrix[date.length()];
|
||||
this.timer = new Timer("Watermark-Timer", true);
|
||||
this.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param format 时间格式
|
||||
* @param width 视频宽度
|
||||
* @param height 视频高度
|
||||
* @param videoProcesser 下个视频处理器
|
||||
*/
|
||||
public WatermarkProcesser(String format, int width, int height, VideoProcesser videoProcesser) {
|
||||
this(format, width, height);
|
||||
this.next = videoProcesser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载水印
|
||||
*/
|
||||
private void init() {
|
||||
final String source = "-: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
final char[] chars = source.toCharArray();
|
||||
for (char value : chars) {
|
||||
this.build(value);
|
||||
}
|
||||
this.timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
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) {
|
||||
WatermarkProcesser.this.watermark[index] = MATRICES[value];
|
||||
index++;
|
||||
@@ -71,21 +115,25 @@ public class WatermarkProcesser extends VideoProcesser {
|
||||
}, 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();
|
||||
paint.setColor(Color.WHITE);
|
||||
paint.setDither(true);
|
||||
paint.setTextSize(40.0F);
|
||||
paint.setTextAlign(Paint.Align.LEFT);
|
||||
paint.setFilterBitmap(true);
|
||||
final Paint.FontMetricsInt box = paint.getFontMetricsInt();
|
||||
final int width = (int) paint.measureText(target);
|
||||
final int height = box.descent - box.ascent;
|
||||
final Paint.FontMetricsInt fontMetricsInt = paint.getFontMetricsInt();
|
||||
final String target = Character.toString(source);
|
||||
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 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();
|
||||
final boolean[][] matrix = new boolean[width][height];
|
||||
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();
|
||||
WatermarkProcesser.MATRICES[source] = new WatermarkMatrix(width, height, matrix);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doProcess(VideoFrame.I420Buffer i420Buffer) {
|
||||
int widthPos = 0;
|
||||
int widthPos = 0;
|
||||
int heightPos = 0;
|
||||
final ByteBuffer buffer = i420Buffer.getDataY();
|
||||
for (WatermarkMatrix matrix : watermark) {
|
||||
for (WatermarkMatrix matrix : this.watermark) {
|
||||
if(matrix == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -117,7 +165,7 @@ public class WatermarkProcesser extends VideoProcesser {
|
||||
}
|
||||
}
|
||||
}
|
||||
widthPos += matrix.width;
|
||||
widthPos += matrix.width;
|
||||
heightPos += matrix.height;
|
||||
}
|
||||
}
|
||||
@@ -128,12 +176,31 @@ public class WatermarkProcesser extends VideoProcesser {
|
||||
this.timer.cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 水印矩阵
|
||||
*
|
||||
* @author acgist
|
||||
*/
|
||||
static class WatermarkMatrix {
|
||||
|
||||
/**
|
||||
* 字符宽度
|
||||
*/
|
||||
int width;
|
||||
/**
|
||||
* 字符高度
|
||||
*/
|
||||
int height;
|
||||
/**
|
||||
* 字符矩阵
|
||||
*/
|
||||
boolean[][] matrix;
|
||||
|
||||
/**
|
||||
* @param width 字符宽度
|
||||
* @param height 字符高度
|
||||
* @param matrix 字符矩阵
|
||||
*/
|
||||
public WatermarkMatrix(int width, int height, boolean[][] matrix) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
Reference in New Issue
Block a user