feat: 控制指令消息改为protobuf二进制
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'com.google.protobuf'
|
||||
}
|
||||
|
||||
def releaseTime() {
|
||||
@@ -116,6 +117,19 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
protobuf {
|
||||
protoc {
|
||||
artifact = 'com.google.protobuf:protoc:3.25.1'
|
||||
}
|
||||
generateProtoTasks {
|
||||
all().each { task ->
|
||||
task.builtins {
|
||||
java {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.11.0'
|
||||
@@ -127,6 +141,8 @@ dependencies {
|
||||
// OkHttp for WebSocket
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
|
||||
|
||||
// Gson for JSON
|
||||
// Gson for JSON(信令消息仍使用 JSON)
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
// Protobuf(DataChannel 控制指令二进制)
|
||||
implementation 'com.google.protobuf:protobuf-java:3.25.1'
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.ttstd.control.Action;
|
||||
import com.ttstd.control.ControlMessage;
|
||||
import com.ttstd.controller.signaling.SignalMessage;
|
||||
import com.ttstd.controller.signaling.WebSocketClient;
|
||||
import com.ttstd.controller.view.RemoteTouchView;
|
||||
@@ -326,55 +328,60 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private void sendTouchCommand(float relX, float relY) {
|
||||
if (webRtcClient != null) {
|
||||
JsonObject cmd = new JsonObject();
|
||||
cmd.addProperty("action", "TOUCH");
|
||||
cmd.addProperty("x", relX);
|
||||
cmd.addProperty("y", relY);
|
||||
webRtcClient.sendControlCommand(cmd.toString());
|
||||
ControlMessage msg = ControlMessage.newBuilder()
|
||||
.setAction(Action.TOUCH)
|
||||
.setX(relX)
|
||||
.setY(relY)
|
||||
.build();
|
||||
webRtcClient.sendControlCommand(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendSwipeCommand(float relX1, float relY1, float relX2, float relY2, long duration) {
|
||||
if (webRtcClient != null) {
|
||||
JsonObject cmd = new JsonObject();
|
||||
cmd.addProperty("action", "SWIPE");
|
||||
cmd.addProperty("x1", relX1);
|
||||
cmd.addProperty("y1", relY1);
|
||||
cmd.addProperty("x2", relX2);
|
||||
cmd.addProperty("y2", relY2);
|
||||
cmd.addProperty("duration", duration);
|
||||
webRtcClient.sendControlCommand(cmd.toString());
|
||||
ControlMessage msg = ControlMessage.newBuilder()
|
||||
.setAction(Action.SWIPE)
|
||||
.setX1(relX1)
|
||||
.setY1(relY1)
|
||||
.setX2(relX2)
|
||||
.setY2(relY2)
|
||||
.setDuration(duration)
|
||||
.build();
|
||||
webRtcClient.sendControlCommand(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendKeyCommand(int keyCode, int action) {
|
||||
if (webRtcClient != null) {
|
||||
JsonObject cmd = new JsonObject();
|
||||
cmd.addProperty("action", "KEY");
|
||||
cmd.addProperty("keyCode", keyCode);
|
||||
cmd.addProperty("keyAction", action);
|
||||
webRtcClient.sendControlCommand(cmd.toString());
|
||||
ControlMessage msg = ControlMessage.newBuilder()
|
||||
.setAction(Action.KEY)
|
||||
.setKeyCode(keyCode)
|
||||
.setKeyAction(action)
|
||||
.build();
|
||||
webRtcClient.sendControlCommand(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendLongPressCommand(float relX, float relY) {
|
||||
if (webRtcClient != null) {
|
||||
JsonObject cmd = new JsonObject();
|
||||
cmd.addProperty("action", "LONG_PRESS");
|
||||
cmd.addProperty("x", relX);
|
||||
cmd.addProperty("y", relY);
|
||||
webRtcClient.sendControlCommand(cmd.toString());
|
||||
ControlMessage msg = ControlMessage.newBuilder()
|
||||
.setAction(Action.LONG_PRESS)
|
||||
.setX(relX)
|
||||
.setY(relY)
|
||||
.build();
|
||||
webRtcClient.sendControlCommand(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMotionEventCommand(int action, float relX, float relY) {
|
||||
if (webRtcClient != null) {
|
||||
JsonObject cmd = new JsonObject();
|
||||
cmd.addProperty("action", "MOTION_EVENT");
|
||||
cmd.addProperty("motionAction", action);
|
||||
cmd.addProperty("x", relX);
|
||||
cmd.addProperty("y", relY);
|
||||
webRtcClient.sendControlCommand(cmd.toString());
|
||||
ControlMessage msg = ControlMessage.newBuilder()
|
||||
.setAction(Action.MOTION_EVENT)
|
||||
.setMotionAction(action)
|
||||
.setX(relX)
|
||||
.setY(relY)
|
||||
.build();
|
||||
webRtcClient.sendControlCommand(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ import android.view.SurfaceView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.ttstd.control.Action;
|
||||
import com.ttstd.control.ControlMessage;
|
||||
|
||||
/**
|
||||
* 自定义SurfaceView,用于捕获触摸事件并转换为远端输入指令。
|
||||
@@ -20,7 +20,6 @@ import com.google.gson.JsonObject;
|
||||
public class RemoteTouchView extends SurfaceView {
|
||||
|
||||
private static final String TAG = "RemoteTouchView";
|
||||
private final Gson gson = new Gson();
|
||||
private TouchEventListener listener;
|
||||
|
||||
private float lastTouchX;
|
||||
@@ -144,39 +143,39 @@ public class RemoteTouchView extends SurfaceView {
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
public String createTouchCommand(float relX, float relY) {
|
||||
JsonObject cmd = new JsonObject();
|
||||
cmd.addProperty("action", "TOUCH");
|
||||
cmd.addProperty("x", relX);
|
||||
cmd.addProperty("y", relY);
|
||||
return cmd.toString();
|
||||
public ControlMessage createTouchCommand(float relX, float relY) {
|
||||
return ControlMessage.newBuilder()
|
||||
.setAction(Action.TOUCH)
|
||||
.setX(relX)
|
||||
.setY(relY)
|
||||
.build();
|
||||
}
|
||||
|
||||
public String createSwipeCommand(float relX1, float relY1, float relX2, float relY2, long duration) {
|
||||
JsonObject cmd = new JsonObject();
|
||||
cmd.addProperty("action", "SWIPE");
|
||||
cmd.addProperty("x1", relX1);
|
||||
cmd.addProperty("y1", relY1);
|
||||
cmd.addProperty("x2", relX2);
|
||||
cmd.addProperty("y2", relY2);
|
||||
cmd.addProperty("duration", duration);
|
||||
return cmd.toString();
|
||||
public ControlMessage createSwipeCommand(float relX1, float relY1, float relX2, float relY2, long duration) {
|
||||
return ControlMessage.newBuilder()
|
||||
.setAction(Action.SWIPE)
|
||||
.setX1(relX1)
|
||||
.setY1(relY1)
|
||||
.setX2(relX2)
|
||||
.setY2(relY2)
|
||||
.setDuration(duration)
|
||||
.build();
|
||||
}
|
||||
|
||||
public String createLongPressCommand(float relX, float relY) {
|
||||
JsonObject cmd = new JsonObject();
|
||||
cmd.addProperty("action", "LONG_PRESS");
|
||||
cmd.addProperty("x", relX);
|
||||
cmd.addProperty("y", relY);
|
||||
return cmd.toString();
|
||||
public ControlMessage createLongPressCommand(float relX, float relY) {
|
||||
return ControlMessage.newBuilder()
|
||||
.setAction(Action.LONG_PRESS)
|
||||
.setX(relX)
|
||||
.setY(relY)
|
||||
.build();
|
||||
}
|
||||
|
||||
public String createMotionEventCommand(int action, float relX, float relY) {
|
||||
JsonObject cmd = new JsonObject();
|
||||
cmd.addProperty("action", "MOTION_EVENT");
|
||||
cmd.addProperty("motionAction", action);
|
||||
cmd.addProperty("x", relX);
|
||||
cmd.addProperty("y", relY);
|
||||
return cmd.toString();
|
||||
public ControlMessage createMotionEventCommand(int action, float relX, float relY) {
|
||||
return ControlMessage.newBuilder()
|
||||
.setAction(Action.MOTION_EVENT)
|
||||
.setMotionAction(action)
|
||||
.setX(relX)
|
||||
.setY(relY)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.ttstd.controller.signaling.SignalMessage;
|
||||
import com.ttstd.controller.signaling.WebSocketClient;
|
||||
import com.ttstd.control.ControlMessage;
|
||||
|
||||
import org.webrtc.DataChannel;
|
||||
import org.webrtc.DefaultVideoDecoderFactory;
|
||||
@@ -27,7 +28,6 @@ import org.webrtc.VideoEncoderFactory;
|
||||
import org.webrtc.VideoTrack;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -231,10 +231,10 @@ public class WebRtcClient {
|
||||
}
|
||||
}
|
||||
|
||||
public void sendControlCommand(String commandJson) {
|
||||
public void sendControlCommand(ControlMessage message) {
|
||||
if (dataChannel != null && dataChannel.state() == DataChannel.State.OPEN) {
|
||||
DataChannel.Buffer buffer = new DataChannel.Buffer(
|
||||
ByteBuffer.wrap(commandJson.getBytes(StandardCharsets.UTF_8)), false);
|
||||
ByteBuffer.wrap(message.toByteArray()), false);
|
||||
dataChannel.send(buffer);
|
||||
}
|
||||
}
|
||||
@@ -279,8 +279,7 @@ public class WebRtcClient {
|
||||
public void onMessage(DataChannel.Buffer buffer) {
|
||||
byte[] data = new byte[buffer.data.remaining()];
|
||||
buffer.data.get(data);
|
||||
String message = new String(data, StandardCharsets.UTF_8);
|
||||
Log.d(TAG, "DataChannel message: " + message);
|
||||
Log.d(TAG, "DataChannel message received, bytes=" + data.length);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
41
WebRTCController/app/src/main/proto/control_message.proto
Normal file
41
WebRTCController/app/src/main/proto/control_message.proto
Normal file
@@ -0,0 +1,41 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package com.ttstd.control;
|
||||
|
||||
option java_package = "com.ttstd.control";
|
||||
option java_multiple_files = true;
|
||||
|
||||
// 控制指令类型,对应原 JSON 字段 action。
|
||||
enum Action {
|
||||
ACTION_UNKNOWN = 0;
|
||||
TOUCH = 1;
|
||||
SWIPE = 2;
|
||||
KEY = 3;
|
||||
LONG_PRESS = 4;
|
||||
MOTION_EVENT = 5;
|
||||
}
|
||||
|
||||
// 通过 RTCDataChannel 传输的控制指令(protobuf 二进制)。
|
||||
// 坐标 x/y/x1/y1/x2/y2 均为相对屏幕的百分比,取值范围 0.0 ~ 1.0。
|
||||
message ControlMessage {
|
||||
// 指令类型
|
||||
Action action = 1;
|
||||
|
||||
// 单点坐标(TOUCH / LONG_PRESS / MOTION_EVENT)
|
||||
double x = 2;
|
||||
double y = 3;
|
||||
|
||||
// 滑动起止坐标(SWIPE)
|
||||
double x1 = 4;
|
||||
double y1 = 5;
|
||||
double x2 = 6;
|
||||
double y2 = 7;
|
||||
int64 duration = 8;
|
||||
|
||||
// 按键(KEY):key_action 0=按下 1=抬起(对应 Android KeyEvent ACTION_DOWN/UP)
|
||||
int32 key_code = 9;
|
||||
int32 key_action = 10;
|
||||
|
||||
// 原始动作(MOTION_EVENT):对应 Android MotionEvent ACTION_*(0=DOWN 1=UP 2=MOVE)
|
||||
int32 motion_action = 11;
|
||||
}
|
||||
Reference in New Issue
Block a user