[*] 电池信号

This commit is contained in:
acgist
2023-03-22 21:03:06 +08:00
parent fb31f5c0a9
commit d635b5a2a3
34 changed files with 812 additions and 832 deletions

View File

@@ -60,3 +60,6 @@ Android还在学习之中...
* 优化JS错误回调 -> platform::error
* 反复测试推流拉流、拉人踢人、音频视频控制
* 24小时不关闭媒体/一秒一次推拉流十分钟测试/三十秒推拉流一小时测试
* AI、美颜、水印、滤镜
* 混音、降噪、回音消除、声音特效

View File

@@ -6,4 +6,4 @@ local.properties
**/build
mediasoup/deps
media/deps

View File

@@ -11,7 +11,6 @@ android {
versionCode 100
versionName "1.0.0"
consumerProguardFiles "consumer-rules.pro"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
@@ -29,6 +28,4 @@ dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

View File

@@ -14,7 +14,7 @@ import com.fasterxml.jackson.annotation.JsonIncludeProperties;
*
* @author acgist
*/
@JsonIncludeProperties(value = { "code", "message", "header", "body" })
@JsonIncludeProperties(value = {"code", "message", "header", "body"})
public class Message implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
@@ -53,7 +53,6 @@ public class Message implements Cloneable, Serializable {
/**
* @param code 状态编码
* @param message 状态描述
*
* @return this
*/
public Message setCode(MessageCode code, String message) {
@@ -71,7 +70,6 @@ public class Message implements Cloneable, Serializable {
/**
* @param body 消息主体
*
* @return 成功消息
*/
public static final Message success(Object body) {
@@ -90,7 +88,6 @@ public class Message implements Cloneable, Serializable {
/**
* @param code 状态编码
*
* @return 失败消息
*/
public static final Message fail(MessageCode code) {
@@ -100,7 +97,6 @@ public class Message implements Cloneable, Serializable {
/**
* @param code 状态编码
* @param body 消息主体
*
* @return 失败消息
*/
public static final Message fail(MessageCode code, Object body) {
@@ -109,7 +105,6 @@ public class Message implements Cloneable, Serializable {
/**
* @param message 状态描述
*
* @return 失败消息
*/
public static final Message fail(String message) {
@@ -119,7 +114,6 @@ public class Message implements Cloneable, Serializable {
/**
* @param message 状态描述
* @param body 消息主体
*
* @return 失败消息
*/
public static final Message fail(String message, Object body) {
@@ -129,7 +123,6 @@ public class Message implements Cloneable, Serializable {
/**
* @param code 状态编码
* @param message 状态描述
*
* @return 失败消息
*/
public static final Message fail(MessageCode code, String message) {
@@ -140,7 +133,6 @@ public class Message implements Cloneable, Serializable {
* @param code 状态编码
* @param message 状态描述
* @param body 消息主体
*
* @return 失败消息
*/
public static final Message fail(MessageCode code, String message, Object body) {
@@ -167,11 +159,11 @@ public class Message implements Cloneable, Serializable {
/**
* @return Map消息主体
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"rawtypes", "unchecked"})
public Map<String, Object> body() {
if(this.body instanceof Map) {
if (this.body instanceof Map) {
return (Map<String, Object>) this.body;
} else if(this.body == null) {
} else if (this.body == null) {
return new HashMap<>();
} else {
throw MessageCodeException.of("信令主体类型错误:" + this.body);

View File

@@ -2,7 +2,7 @@ package com.acgist.taoyao.boot.model;
/**
* 状态编码
*
* <p>
* 1xxx = 前置错误
* 2xxx = 内部错误
* 3xxx = 请求错误
@@ -63,7 +63,6 @@ public enum MessageCode {
/**
* @param code 状态编码
*
* @return 状态编码
*/
public static final MessageCode of(String code) {
@@ -78,7 +77,6 @@ public enum MessageCode {
/**
* @param status HTTP Status
*
* @return 状态编码
*/
public static final MessageCode of(Integer status) {

View File

@@ -18,7 +18,6 @@ public class MessageCodeException extends RuntimeException {
/**
* @param message 异常消息
*
* @return 状态编码异常
*/
public static final MessageCodeException of(String message) {
@@ -28,7 +27,6 @@ public class MessageCodeException extends RuntimeException {
/**
* @param t 异常
* @param message 异常消息
*
* @return 状态编码异常
*/
public static final MessageCodeException of(Throwable t, String message) {
@@ -38,7 +36,6 @@ public class MessageCodeException extends RuntimeException {
/**
* @param code 状态编码
* @param message 异常消息
*
* @return 状态编码异常
*/
public static final MessageCodeException of(MessageCode code, String message) {
@@ -49,14 +46,13 @@ public class MessageCodeException extends RuntimeException {
* @param t 异常
* @param code 状态编码
* @param message 异常消息
*
* @return 状态编码异常
*/
public static final MessageCodeException of(Throwable t, MessageCode code, String message) {
if(code == null) {
if (code == null) {
code = MessageCode.CODE_9999;
}
if(message == null || message.isEmpty()) {
if (message == null || message.isEmpty()) {
message = Objects.isNull(t) ? code.getMessage() : t.getMessage();
}
return new MessageCodeException(t, code, message);

View File

@@ -19,7 +19,7 @@ public final class CloseableUtils {
*/
public static final void close(Closeable closeable) {
try {
if(closeable != null) {
if (closeable != null) {
closeable.close();
}
} catch (Exception e) {
@@ -34,7 +34,7 @@ public final class CloseableUtils {
*/
public static final void close(AutoCloseable closeable) {
try {
if(closeable != null) {
if (closeable != null) {
closeable.close();
}
} catch (Exception e) {

View File

@@ -81,6 +81,7 @@ public final class DateUtils {
this.format = format;
this.dateTimeFormatter = DateTimeFormatter.ofPattern(format);
}
public String getFormat() {
return this.format;
}
@@ -140,6 +141,7 @@ public final class DateUtils {
this.format = format;
this.dateTimeFormatter = DateTimeFormatter.ofPattern(format);
}
public String getFormat() {
return this.format;
}
@@ -154,7 +156,6 @@ public final class DateUtils {
* 生成时间戳
*
* @return 时间戳
*
* @see #buildTime(LocalDateTime)
*/
public static final String buildTime() {
@@ -165,7 +166,6 @@ public final class DateUtils {
* 生成时间戳
*
* @param localDateTime 日期时间
*
* @return 时间戳
*/
public static final String buildTime(LocalDateTime localDateTime) {
@@ -179,7 +179,6 @@ public final class DateUtils {
* 日期转化
*
* @param date Date
*
* @return LocalDate
*/
public static final LocalDate toLocalDate(Date date) {
@@ -190,7 +189,6 @@ public final class DateUtils {
* 日期转化
*
* @param date Date
*
* @return LocalTime
*/
public static final LocalTime toLocalTime(Date date) {
@@ -201,7 +199,6 @@ public final class DateUtils {
* 日期转化
*
* @param date Date
*
* @return LocalDateTime
*/
public static final LocalDateTime toLocalDateTime(Date date) {
@@ -212,7 +209,6 @@ public final class DateUtils {
* 转换毫秒
*
* @param localDateTime LocalDateTime
*
* @return 毫秒
*/
public static final long toMilli(LocalDateTime localDateTime) {
@@ -224,7 +220,6 @@ public final class DateUtils {
*
* @param localDate LocalDate
* @param format 格式
*
* @return 日期字符串
*/
public static String format(LocalDate localDate, DateStyle format) {
@@ -236,7 +231,6 @@ public final class DateUtils {
*
* @param localTime LocalTime
* @param format 格式
*
* @return 时间字符串
*/
public static String format(LocalTime localTime, TimeStyle format) {
@@ -248,7 +242,6 @@ public final class DateUtils {
*
* @param localDateTime LocalDateTime
* @param format 格式
*
* @return 日期时间字符串
*/
public static String format(LocalDateTime localDateTime, DateTimeStyle format) {

View File

@@ -42,7 +42,6 @@ public final class JSONUtils {
* Java转JSON
*
* @param object Java
*
* @return JSON
*/
public static final String toJSON(Object object) {
@@ -60,9 +59,7 @@ public final class JSONUtils {
* JSON转Java
*
* @param <T> Java类型
*
* @param json JSON
*
* @return Java
*/
public static final <T> T toJava(String json) {
@@ -81,10 +78,8 @@ public final class JSONUtils {
* JSON转Java
*
* @param <T> Java类型
*
* @param json JSON
* @param clazz Java类型
*
* @return Java
*/
public static final <T> T toJava(String json, Class<T> clazz) {
@@ -102,10 +97,8 @@ public final class JSONUtils {
* JSON转Java
*
* @param <T> Java类型
*
* @param json JSON
* @param type Java类型
*
* @return Java
*/
public static final <T> T toJava(String json, TypeReference<T> type) {
@@ -124,9 +117,7 @@ public final class JSONUtils {
*
* @param <K> K类型
* @param <V> V类型
*
* @param json JSON
*
* @return Map
*/
public static final <K, V> Map<K, V> toMap(String json) {
@@ -145,9 +136,7 @@ public final class JSONUtils {
* JSON转List
*
* @param <T> 元素类型
*
* @param json JSON
*
* @return List
*/
public static final <T> List<T> toList(String json) {
@@ -166,10 +155,8 @@ public final class JSONUtils {
* JSON转List
*
* @param <T> 元素类型
*
* @param json JSON
* @param clazz 类型
*
* @return List
*/
public static final <T> List<T> toList(String json, Class<T> clazz) {

View File

@@ -30,13 +30,11 @@ android {
dependencies {
implementation project(path: ':boot')
implementation project(path: ':mediasoup')
implementation project(path: ':media')
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

View File

@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"

View File

@@ -3,5 +3,5 @@ package com.acgist.taoyao.client.media;
/**
* 终端
*/
public class MediaClient {
public class Client {
}

View File

@@ -0,0 +1,4 @@
package com.acgist.taoyao.client.media;
public class Room {
}

View File

@@ -1,15 +1,13 @@
package com.acgist.taoyao.client.signal;
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import com.acgist.taoyao.boot.model.Header;
import com.acgist.taoyao.boot.model.Message;
import com.acgist.taoyao.boot.utils.CloseableUtils;
import com.acgist.taoyao.boot.utils.JSONUtils;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
@@ -24,6 +22,12 @@ import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
/**
* 桃夭信令
*
@@ -38,19 +42,21 @@ public class Taoyao {
/**
* 端口
*/
private int port;
private final int port;
/**
* 地址
*/
private String host;
private final String host;
private final String clientId;
private final String name;
private final String username;
private final String password;
/**
* Socket
*/
private Socket socket;
private InputStream input;
private OutputStream output;
private String username;
private String password;
private boolean close;
/**
* 是否连接
@@ -58,13 +64,18 @@ public class Taoyao {
private boolean connect;
private final Cipher encrypt;
private final Cipher decrypt;
private final WifiManager wifiManager;
private final BatteryManager batteryManager;
public Taoyao(int port, String host, String algo, String secret) {
public Taoyao(
int port, String host, String algo, String secret, String clientId, String name, String username, String password,
WifiManager wifiManager, BatteryManager batteryManager
) {
this.port = port;
this.host = host;
this.close = false;
this.connect = false;
if(algo == null || algo.isEmpty() || algo.equals("PLAINTEXT")) {
if (algo == null || algo.isEmpty() || algo.equals("PLAINTEXT")) {
// 明文
this.encrypt = null;
this.decrypt = null;
@@ -72,6 +83,12 @@ public class Taoyao {
this.encrypt = this.buildCipher(Cipher.ENCRYPT_MODE, algo, secret);
this.decrypt = this.buildCipher(Cipher.DECRYPT_MODE, algo, secret);
}
this.clientId = clientId;
this.name = name;
this.username = username;
this.password = password;
this.wifiManager = wifiManager;
this.batteryManager = batteryManager;
EXECUTOR.submit(this::read);
}
@@ -97,7 +114,7 @@ public class Taoyao {
try {
// socket.setSoTimeout(5000);
this.socket.connect(new InetSocketAddress(this.host, this.port), 5000);
if(this.socket.isConnected()) {
if (this.socket.isConnected()) {
this.input = this.socket.getInputStream();
this.output = this.socket.getOutputStream();
this.register();
@@ -116,9 +133,9 @@ public class Taoyao {
short messageLength = 0;
final byte[] bytes = new byte[1024];
final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
while(!this.close) {
while (!this.close) {
try {
while(this.input == null) {
while (this.input == null) {
this.connect();
synchronized (this) {
this.wait(5000);
@@ -168,12 +185,11 @@ public class Taoyao {
/**
* @param message 消息
*
* @return 加密消息
*/
private byte[] encrypt(Message message) {
final byte[] bytes = message.toString().getBytes();
if(this.encrypt != null) {
if (this.encrypt != null) {
try {
// 加密
final byte[] encryptBytes = this.encrypt.doFinal(bytes);
@@ -194,7 +210,7 @@ public class Taoyao {
}
public void push(Message message) {
if(this.output == null) {
if (this.output == null) {
return;
}
try {
@@ -212,14 +228,21 @@ public class Taoyao {
final Header header = new Header();
this.push(this.buildMessage(
"client::register",
"clientId", "harmony",
"name", "harmony",
"clientId", this.clientId,
"name", this.name,
"clientType", "camera",
"username", "taoyao",
"password","taoyao"
"username", this.username,
"password", this.password,
"signal", this.wifiManager.getMaxSignalLevel(),
"batter", this.batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY),
"charging", this.batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_STATUS)
));
}
private void heartbeat() {
}
private void close() {
this.connect = false;
CloseableUtils.close(this.input);
@@ -267,10 +290,10 @@ public class Taoyao {
private String version;
public Message buildMessage(String signal, Object ... args) {
public Message buildMessage(String signal, Object... args) {
final Map<Object, Object> map = new HashMap<>();
if(args != null) {
for (int index = 0; index < args.length; index+=2) {
if (args != null) {
for (int index = 0; index < args.length; index += 2) {
map.put(args[index], args[index + 1]);
}
}
@@ -293,11 +316,11 @@ public class Taoyao {
// log.debug("收到消息:{}", new String(this.decrypt.doFinal(message)));
System.out.println(content);
final Message message = JSONUtils.toJava(content, Message.class);
if(message == null) {
if (message == null) {
return;
}
final Header header = message.getHeader();
if(header == null) {
if (header == null) {
return;
}
final Map<String, Object> body = message.body();

View File

@@ -0,0 +1,67 @@
cmake_minimum_required(VERSION 3.22.1)
project(taoyao VERSION 1.0.0 LANGUAGES C CXX)
# Debug | Release
#-DCMAKE_BUILD_TYPE=Debug
#set(CMAKE_BUILD_TYPE Debug)
# C编译选项
set(CMAKE_C_STANDARD 17)
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c17 -O3")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -std=c17 -O0 -g")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -std=c17 -O3")
# C++编译选项
set(CMAKE_CXX_STANDARD 17)
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -O3")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++17 -O0 -g")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++17 -O3")
set(
SOURCE_DIR
src/main/cpp/
)
set(
SOURCE_FILES
${SOURCE_DIR}/main.hpp
${SOURCE_DIR}/main.cpp
)
set(LIBWEBRTC_BINARY_PATH ${LIBWEBRTC_BINARY_PATH}/${ANDROID_ABI} CACHE STRING "libwebrtc binary path" FORCE)
if (${MEDIASOUPCLIENT_LOG_TRACE})
target_compile_definitions(
${PROJECT_NAME} PRIVATE MSC_LOG_TRACE=1
)
endif ()
if (${MEDIASOUPCLIENT_LOG_DEV})
target_compile_definitions(
${PROJECT_NAME} PRIVATE MSC_LOG_DEV=1
)
endif ()
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
add_subdirectory("deps/libmediasoupclient")
set_source_files_properties(
${SOURCE_FILES} PROPERTIES COMPILE_FLAGS -Wall -Wextra -Wpedantic
)
target_include_directories(
${PROJECT_NAME} PUBLIC
"${SOURCE_DIR}/include"
"${PROJECT_SOURCE_DIR}/deps/libmediasoupclient/include"
"${PROJECT_SOURCE_DIR}/deps/libmediasoupclient/deps/libsdptransform/include"
)
target_link_libraries(
${PROJECT_NAME} PUBLIC
log
android
OpenSLES
mediasoupclient
)

View File

@@ -14,7 +14,6 @@ android {
versionCode 100
versionName "1.0.0"
consumerProguardFiles "consumer-rules.pro"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cFlags '-std=c17'
@@ -48,11 +47,8 @@ android {
}
dependencies {
api fileTree(dir: WEBRTC_LIB_PATH, include: ['libwebrtc.jar'])
implementation fileTree(dir: 'libs', include: ['*.a', '*.so', '*.jar'])
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

View File

@@ -5,10 +5,11 @@
extern "C" JNIEXPORT jstring JNICALL
Java_com_acgist_taoyao_client_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
JNIEnv *env,
jobject /* this */
) {
mediasoupclient::Device device;
if(device.IsLoaded()) {
if (device.IsLoaded()) {
std::string hello = "Hello from C++ true";
return env->NewStringUTF(hello.c_str());
} else {

View File

@@ -1,76 +0,0 @@
cmake_minimum_required(VERSION 3.22.1)
project(taoyao VERSION 1.0.0 LANGUAGES C CXX)
# Debug | Release
# -DCMAKE_BUILD_TYPE=Debug
# set(CMAKE_BUILD_TYPE Debug)
# C编译选项
#set(CMAKE_C_STANDARD 17)
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c17 -O3")
#set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -std=c17 -O0 -g")
#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -std=c17 -O3")
# C++编译选项
#set(CMAKE_CXX_STANDARD 17)
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -O3")
#set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++17 -O0 -g")
#set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++17 -O3")
set(
SOURCE_DIR
src/main/cpp/
)
set(
SOURCE_FILES
${SOURCE_DIR}/main.hpp
${SOURCE_DIR}/main.cpp
)
set(LIBWEBRTC_BINARY_PATH ${LIBWEBRTC_BINARY_PATH}/${ANDROID_ABI} CACHE STRING "libwebrtc binary path" FORCE)
if (${MEDIASOUPCLIENT_LOG_TRACE})
target_compile_definitions(
${PROJECT_NAME} PRIVATE MSC_LOG_TRACE=1
)
endif ()
if (${MEDIASOUPCLIENT_LOG_DEV})
target_compile_definitions(
${PROJECT_NAME} PRIVATE MSC_LOG_DEV=1
)
endif ()
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
add_subdirectory("deps/libmediasoupclient")
set_source_files_properties(
${SOURCE_FILES} PROPERTIES COMPILE_FLAGS -Wall -Wextra -Wpedantic
)
target_include_directories(
${PROJECT_NAME} PUBLIC
"${SOURCE_DIR}/include"
"${PROJECT_SOURCE_DIR}/deps/libmediasoupclient/include"
"${PROJECT_SOURCE_DIR}/deps/libmediasoupclient/deps/libsdptransform/include"
)
target_compile_definitions(
${PROJECT_NAME} PUBLIC
$<$<NOT:$<PLATFORM_ID:Windows>>:WEBRTC_POSIX>
$<$<PLATFORM_ID:Darwin>:WEBRTC_MAC>
$<$<PLATFORM_ID:Windows>:NOMINMAX>
$<$<PLATFORM_ID:Windows>:WEBRTC_WIN>
$<$<PLATFORM_ID:Windows>:WIN32_LEAN_AND_MEAN>
)
target_link_libraries(
${PROJECT_NAME} PUBLIC
log
android
OpenSLES
mediasoupclient
)

View File

@@ -14,5 +14,5 @@ dependencyResolutionManagement {
}
rootProject.name = "taoyao"
include ':boot'
include ':media'
include ':client'
include ':mediasoup'

View File

@@ -12,4 +12,3 @@
## 信令格式
[信令格式](https://localhost:8888/protocol/list)