[*] 每日优化
This commit is contained in:
@@ -30,6 +30,7 @@ getter/setter
|
|||||||
|
|
||||||
## 计划任务
|
## 计划任务
|
||||||
|
|
||||||
|
* 开机自启
|
||||||
* 录制底噪
|
* 录制底噪
|
||||||
* 分辨率调整
|
* 分辨率调整
|
||||||
* 降低视频录制大小
|
* 降低视频录制大小
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -53,4 +53,11 @@ public final class IdUtils {
|
|||||||
IdUtils.clientIndex = clientIndex;
|
IdUtils.clientIndex = clientIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 随机INT
|
||||||
|
*/
|
||||||
|
public static final int nextInt() {
|
||||||
|
return (int) (System.nanoTime() % Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,10 @@
|
|||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
android:theme="@style/Theme.Taoyao">
|
android:theme="@style/Theme.Taoyao">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.HOME" />
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<action android:name="android.intent.action.DEFAULT" />
|
<!--
|
||||||
|
<category android:name="android.intent.category.HOME" />
|
||||||
|
-->
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.acgist.taoyao.client;
|
|||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
@@ -26,14 +25,12 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
|
|
||||||
|
import com.acgist.taoyao.boot.utils.IdUtils;
|
||||||
import com.acgist.taoyao.client.databinding.ActivityMainBinding;
|
import com.acgist.taoyao.client.databinding.ActivityMainBinding;
|
||||||
import com.acgist.taoyao.media.MediaManager;
|
import com.acgist.taoyao.media.MediaManager;
|
||||||
import com.acgist.taoyao.media.VideoSourceType;
|
|
||||||
import com.acgist.taoyao.media.config.Config;
|
import com.acgist.taoyao.media.config.Config;
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
|
||||||
import org.apache.commons.lang3.RandomUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -129,7 +126,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
if (Stream.of(permissions).map(this.getApplicationContext()::checkSelfPermission).allMatch(v -> v == PackageManager.PERMISSION_GRANTED)) {
|
if (Stream.of(permissions).map(this.getApplicationContext()::checkSelfPermission).allMatch(v -> v == PackageManager.PERMISSION_GRANTED)) {
|
||||||
Log.i(MediaService.class.getSimpleName(), "授权成功");
|
Log.i(MediaService.class.getSimpleName(), "授权成功");
|
||||||
} else {
|
} else {
|
||||||
ActivityCompat.requestPermissions(this, permissions, RandomUtils.nextInt());
|
ActivityCompat.requestPermissions(this, permissions, IdUtils.nextInt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,28 +139,10 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
Log.i(MainActivity.class.getSimpleName(), "拉起媒体服务");
|
Log.i(MainActivity.class.getSimpleName(), "拉起媒体服务");
|
||||||
this.mainHandler = new MainHandler();
|
this.mainHandler = new MainHandler();
|
||||||
final Context context = this.getApplicationContext();
|
|
||||||
final Resources resources = this.getResources();
|
|
||||||
final MediaManager mediaManager = MediaManager.getInstance();
|
|
||||||
mediaManager.initContext(
|
|
||||||
this.mainHandler, context,
|
|
||||||
resources.getInteger(R.integer.imageQuantity),
|
|
||||||
resources.getString(R.string.audioQuantity),
|
|
||||||
resources.getString(R.string.videoQuantity),
|
|
||||||
resources.getInteger(R.integer.channelCount),
|
|
||||||
resources.getInteger(R.integer.iFrameInterval),
|
|
||||||
resources.getString(R.string.storagePathImage),
|
|
||||||
resources.getString(R.string.storagePathVideo),
|
|
||||||
resources.getString(R.string.watermark),
|
|
||||||
VideoSourceType.valueOf(resources.getString(R.string.videoSourceType))
|
|
||||||
);
|
|
||||||
if(resources.getBoolean(R.bool.broadcaster)) {
|
|
||||||
mediaManager.initTTS(context);
|
|
||||||
}
|
|
||||||
// 注意:不能使用intent传递
|
// 注意:不能使用intent传递
|
||||||
MediaService.mainHandler = this.mainHandler;
|
MediaService.setMainHandler(this.mainHandler);
|
||||||
final Intent intent = new Intent(this, MediaService.class);
|
final Intent intent = new Intent(this, MediaService.class);
|
||||||
intent.setAction(MediaService.Action.CONNECT.name());
|
intent.setAction(MediaService.Action.LAUNCH.name());
|
||||||
this.startService(intent);
|
this.startService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +160,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
if (result.getResultCode() == Activity.RESULT_OK) {
|
if (result.getResultCode() == Activity.RESULT_OK) {
|
||||||
Log.i(MediaManager.class.getSimpleName(), "屏幕捕获成功");
|
Log.i(MediaManager.class.getSimpleName(), "屏幕捕获成功");
|
||||||
final Intent intent = new Intent(this, MediaService.class);
|
final Intent intent = new Intent(this, MediaService.class);
|
||||||
intent.setAction(MediaService.Action.SCREEN_RECORD.name());
|
intent.setAction(MediaService.Action.SCREEN_CAPTURE.name());
|
||||||
intent.putExtra("data", result.getData());
|
intent.putExtra("data", result.getData());
|
||||||
intent.putExtra("code", result.getResultCode());
|
intent.putExtra("code", result.getResultCode());
|
||||||
this.startService(intent);
|
this.startService(intent);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import android.content.Intent;
|
|||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.media.AudioManager;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -19,8 +20,10 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
|
|
||||||
|
import com.acgist.taoyao.boot.utils.IdUtils;
|
||||||
import com.acgist.taoyao.client.signal.Taoyao;
|
import com.acgist.taoyao.client.signal.Taoyao;
|
||||||
import com.acgist.taoyao.media.MediaManager;
|
import com.acgist.taoyao.media.MediaManager;
|
||||||
|
import com.acgist.taoyao.media.VideoSourceType;
|
||||||
import com.acgist.taoyao.media.signal.ITaoyaoListener;
|
import com.acgist.taoyao.media.signal.ITaoyaoListener;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -35,6 +38,7 @@ import java.nio.file.Paths;
|
|||||||
public class MediaService extends Service {
|
public class MediaService extends Service {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
Log.i(MediaService.class.getSimpleName(), "加载C++库文件");
|
||||||
System.loadLibrary("taoyao");
|
System.loadLibrary("taoyao");
|
||||||
System.loadLibrary("jingle_peerconnection_so");
|
System.loadLibrary("jingle_peerconnection_so");
|
||||||
}
|
}
|
||||||
@@ -46,20 +50,28 @@ public class MediaService extends Service {
|
|||||||
*/
|
*/
|
||||||
public enum Action {
|
public enum Action {
|
||||||
|
|
||||||
// 启动
|
/**
|
||||||
|
* 系统启动
|
||||||
|
*/
|
||||||
|
BOOT,
|
||||||
|
/**
|
||||||
|
* 连接信令
|
||||||
|
*/
|
||||||
LAUNCH,
|
LAUNCH,
|
||||||
// 连接
|
/**
|
||||||
CONNECT,
|
* 重连信令
|
||||||
// 重连
|
*/
|
||||||
RECONNECT,
|
RECONNECT,
|
||||||
// 屏幕录制
|
/**
|
||||||
SCREEN_RECORD;
|
* 屏幕录制
|
||||||
|
*/
|
||||||
|
SCREEN_CAPTURE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Handler mainHandler;
|
|
||||||
|
|
||||||
private Taoyao taoyao;
|
private Taoyao taoyao;
|
||||||
|
private static Handler mainHandler;
|
||||||
|
private static final String TAOYAO = "TAOYAO";
|
||||||
private final ITaoyaoListener taoyaoListener = new ITaoyaoListener() {
|
private final ITaoyaoListener taoyaoListener = new ITaoyaoListener() {
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,6 +91,7 @@ public class MediaService extends Service {
|
|||||||
final Resources resources = this.getResources();
|
final Resources resources = this.getResources();
|
||||||
this.mkdir(resources.getString(R.string.storagePathImage), Environment.DIRECTORY_PICTURES);
|
this.mkdir(resources.getString(R.string.storagePathImage), Environment.DIRECTORY_PICTURES);
|
||||||
this.mkdir(resources.getString(R.string.storagePathVideo), Environment.DIRECTORY_MOVIES);
|
this.mkdir(resources.getString(R.string.storagePathVideo), Environment.DIRECTORY_MOVIES);
|
||||||
|
this.settingAudio();
|
||||||
this.buildNotificationChannel();
|
this.buildNotificationChannel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,16 +104,16 @@ public class MediaService extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
Log.i(MediaService.class.getSimpleName(), "onStartCommand:" + intent.getAction());
|
Log.i(MediaService.class.getSimpleName(), "onStartCommand:" + intent.getAction());
|
||||||
this.cleanAllNotification();
|
if (Action.BOOT.name().equals(intent.getAction())) {
|
||||||
if (Action.LAUNCH.name().equals(intent.getAction())) {
|
this.boot();
|
||||||
this.launch(intent);
|
this.openConnect();
|
||||||
this.openConnect(intent);
|
} else if (Action.LAUNCH.name().equals(intent.getAction())) {
|
||||||
} else if (Action.CONNECT.name().equals(intent.getAction())) {
|
this.launch();
|
||||||
this.openConnect(intent);
|
this.openConnect();
|
||||||
} else if (Action.RECONNECT.name().equals(intent.getAction())) {
|
} else if (Action.RECONNECT.name().equals(intent.getAction())) {
|
||||||
this.reconnect();
|
this.reconnect();
|
||||||
} else if (Action.SCREEN_RECORD.name().equals(intent.getAction())) {
|
} else if (Action.SCREEN_CAPTURE.name().equals(intent.getAction())) {
|
||||||
this.screenRecord(intent);
|
this.screenCapture(intent);
|
||||||
} else {
|
} else {
|
||||||
Log.w(MediaService.class.getSimpleName(), "未知动作:" + intent.getAction());
|
Log.w(MediaService.class.getSimpleName(), "未知动作:" + intent.getAction());
|
||||||
}
|
}
|
||||||
@@ -114,20 +127,48 @@ public class MediaService extends Service {
|
|||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void launch(Intent intent) {
|
/**
|
||||||
final Intent notificationIntent = new Intent(this, MediaService.class);
|
* 启动
|
||||||
final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
|
*/
|
||||||
final NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "TAOYAO")
|
private void boot() {
|
||||||
|
final Intent activityIntent = new Intent(this, MainActivity.class);
|
||||||
|
final PendingIntent pendingIntent = PendingIntent.getActivity(this, IdUtils.nextInt(), activityIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||||
|
final NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, TAOYAO)
|
||||||
.setSmallIcon(R.mipmap.ic_launcher_foreground)
|
.setSmallIcon(R.mipmap.ic_launcher_foreground)
|
||||||
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher_foreground))
|
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher_foreground))
|
||||||
.setContentTitle("桃夭后台")
|
.setContentTitle("桃夭后台")
|
||||||
.setContentText("桃夭正在后台运行")
|
.setContentText("桃夭正在后台运行")
|
||||||
.setContentIntent(pendingIntent);
|
.setContentIntent(pendingIntent);
|
||||||
final Notification notification = notificationBuilder.build();
|
final Notification notification = notificationBuilder.build();
|
||||||
this.startForeground((int) System.currentTimeMillis(), notification);
|
this.startForeground(IdUtils.nextInt(), notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openConnect(Intent intent) {
|
/**
|
||||||
|
* 启动
|
||||||
|
*/
|
||||||
|
private void launch() {
|
||||||
|
final Context context = this.getApplicationContext();
|
||||||
|
final Resources resources = this.getResources();
|
||||||
|
final MediaManager mediaManager = MediaManager.getInstance();
|
||||||
|
mediaManager.initContext(
|
||||||
|
MediaService.mainHandler, context,
|
||||||
|
resources.getInteger(R.integer.imageQuantity),
|
||||||
|
resources.getString(R.string.audioQuantity),
|
||||||
|
resources.getString(R.string.videoQuantity),
|
||||||
|
resources.getInteger(R.integer.channelCount),
|
||||||
|
resources.getInteger(R.integer.iFrameInterval),
|
||||||
|
resources.getString(R.string.storagePathImage),
|
||||||
|
resources.getString(R.string.storagePathVideo),
|
||||||
|
resources.getBoolean(R.bool.broadcaster),
|
||||||
|
resources.getString(R.string.watermark),
|
||||||
|
VideoSourceType.valueOf(resources.getString(R.string.videoSourceType))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接信令
|
||||||
|
*/
|
||||||
|
private void openConnect() {
|
||||||
if (this.taoyao == null) {
|
if (this.taoyao == null) {
|
||||||
Log.d(MediaService.class.getSimpleName(), "打开信令连接");
|
Log.d(MediaService.class.getSimpleName(), "打开信令连接");
|
||||||
this.connect();
|
this.connect();
|
||||||
@@ -136,6 +177,9 @@ public class MediaService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重连信令
|
||||||
|
*/
|
||||||
private void reconnect() {
|
private void reconnect() {
|
||||||
Log.d(MediaService.class.getSimpleName(), "重新连接信令");
|
Log.d(MediaService.class.getSimpleName(), "重新连接信令");
|
||||||
this.connect();
|
this.connect();
|
||||||
@@ -147,15 +191,14 @@ public class MediaService extends Service {
|
|||||||
private synchronized void connect() {
|
private synchronized void connect() {
|
||||||
// 加载配置
|
// 加载配置
|
||||||
final SharedPreferences sharedPreferences = this.getSharedPreferences("settings", Context.MODE_PRIVATE);
|
final SharedPreferences sharedPreferences = this.getSharedPreferences("settings", Context.MODE_PRIVATE);
|
||||||
final int port = sharedPreferences.getInt("settings.port", 9999);
|
final int port = sharedPreferences.getInt("settings.port", 9999);
|
||||||
final String host = sharedPreferences.getString("settings.host", "192.168.1.100");
|
final String host = sharedPreferences.getString("settings.host", "192.168.1.100");
|
||||||
final String name = sharedPreferences.getString("settings.name", "移动端");
|
final String name = sharedPreferences.getString("settings.name", "移动端");
|
||||||
final String clientId = sharedPreferences.getString("settings.clientId", "mobile");
|
final String clientId = sharedPreferences.getString("settings.clientId", "mobile");
|
||||||
final String username = sharedPreferences.getString("settings.username", "taoyao");
|
final String username = sharedPreferences.getString("settings.username", "taoyao");
|
||||||
final String password = sharedPreferences.getString("settings.password", "taoyao");
|
final String password = sharedPreferences.getString("settings.password", "taoyao");
|
||||||
|
final Context context = this.getApplicationContext();
|
||||||
final Resources resources = this.getResources();
|
final Resources resources = this.getResources();
|
||||||
// 系统服务
|
|
||||||
final Context context = this.getApplicationContext();
|
|
||||||
this.close();
|
this.close();
|
||||||
// 连接信令
|
// 连接信令
|
||||||
this.taoyao = new Taoyao(
|
this.taoyao = new Taoyao(
|
||||||
@@ -165,9 +208,31 @@ public class MediaService extends Service {
|
|||||||
this.mainHandler, context, this.taoyaoListener
|
this.mainHandler, context, this.taoyaoListener
|
||||||
);
|
);
|
||||||
MediaManager.getInstance().initTaoyao(this.taoyao);
|
MediaManager.getInstance().initTaoyao(this.taoyao);
|
||||||
Toast.makeText(this.getApplicationContext(), "连接信令", Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, "连接信令", Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 屏幕录制
|
||||||
|
*
|
||||||
|
* @param intent Intent
|
||||||
|
*/
|
||||||
|
public void screenCapture(Intent intent) {
|
||||||
|
final Intent activityIntent = new Intent(this, MainActivity.class);
|
||||||
|
final PendingIntent pendingIntent = PendingIntent.getActivity(this, IdUtils.nextInt(), activityIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||||
|
final NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, TAOYAO)
|
||||||
|
.setSmallIcon(R.mipmap.ic_launcher_foreground)
|
||||||
|
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher_foreground))
|
||||||
|
.setContentTitle("录制屏幕")
|
||||||
|
.setContentText("桃夭正在录制屏幕")
|
||||||
|
.setContentIntent(pendingIntent);
|
||||||
|
final Notification notification = notificationBuilder.build();
|
||||||
|
this.startForeground((int) System.currentTimeMillis(), notification);
|
||||||
|
MediaManager.getInstance().initScreen(intent.getParcelableExtra("data"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭连接
|
||||||
|
*/
|
||||||
private synchronized void close() {
|
private synchronized void close() {
|
||||||
if (this.taoyao == null) {
|
if (this.taoyao == null) {
|
||||||
return;
|
return;
|
||||||
@@ -177,22 +242,12 @@ public class MediaService extends Service {
|
|||||||
this.taoyao = null;
|
this.taoyao = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void screenRecord(Intent intent) {
|
/**
|
||||||
final Intent notificationIntent = new Intent(this, MediaService.class);
|
* 创建目录
|
||||||
final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
|
*
|
||||||
final NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "TAOYAO")
|
* @param path 路径
|
||||||
.setSmallIcon(R.mipmap.ic_launcher_foreground)
|
* @param type 类型
|
||||||
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher_foreground))
|
*/
|
||||||
// 自动清除
|
|
||||||
// .setAutoCancel(true)
|
|
||||||
.setContentTitle("录制屏幕")
|
|
||||||
.setContentText("桃夭正在录制屏幕")
|
|
||||||
.setContentIntent(pendingIntent);
|
|
||||||
final Notification notification = notificationBuilder.build();
|
|
||||||
this.startForeground((int) System.currentTimeMillis(), notification);
|
|
||||||
MediaManager.getInstance().initScreen(intent.getParcelableExtra("data"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void mkdir(String path, String type) {
|
private void mkdir(String path, String type) {
|
||||||
final Path imagePath = Paths.get(
|
final Path imagePath = Paths.get(
|
||||||
Environment.getExternalStoragePublicDirectory(type).getAbsolutePath(),
|
Environment.getExternalStoragePublicDirectory(type).getAbsolutePath(),
|
||||||
@@ -201,23 +256,42 @@ public class MediaService extends Service {
|
|||||||
final File file = imagePath.toFile();
|
final File file = imagePath.toFile();
|
||||||
if(file.exists()) {
|
if(file.exists()) {
|
||||||
Log.d(MediaService.class.getSimpleName(), "目录已经存在:" + imagePath);
|
Log.d(MediaService.class.getSimpleName(), "目录已经存在:" + imagePath);
|
||||||
|
} else if(file.mkdirs()) {
|
||||||
|
Log.d(MediaService.class.getSimpleName(), "新建目录成功:" + imagePath);
|
||||||
} else {
|
} else {
|
||||||
Log.d(MediaService.class.getSimpleName(), "新建文件目录:" + imagePath);
|
Log.d(MediaService.class.getSimpleName(), "新建目录失败:" + imagePath);
|
||||||
file.mkdirs();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置音频
|
||||||
|
*/
|
||||||
|
private void settingAudio() {
|
||||||
|
final AudioManager audioManager = this.getApplicationContext().getSystemService(AudioManager.class);
|
||||||
|
Log.i(MediaService.class.getSimpleName(), "当前音频模式:" + audioManager.getMode());
|
||||||
|
Log.i(MediaService.class.getSimpleName(), "当前音频音量:" + audioManager.getStreamVolume(audioManager.getMode()));
|
||||||
|
// Log.i(MediaService.class.getSimpleName(), "当前蓝牙是否打开:" + audioManager.isBluetoothScoOn());
|
||||||
|
// Log.i(MediaService.class.getSimpleName(), "当前耳机是否打开:" + audioManager.isWiredHeadsetOn());
|
||||||
|
// Log.i(MediaService.class.getSimpleName(), "当前电话扬声器是否打开:" + audioManager.isSpeakerphoneOn());
|
||||||
|
// audioManager.setStreamVolume(AudioManager.MODE_IN_COMMUNICATION, audioManager.getStreamMaxVolume(AudioManager.MODE_IN_COMMUNICATION), AudioManager.FLAG_PLAY_SOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新建通知通道
|
||||||
|
*/
|
||||||
private void buildNotificationChannel() {
|
private void buildNotificationChannel() {
|
||||||
final NotificationChannel channel = new NotificationChannel("TAOYAO", "桃夭通知", NotificationManager.IMPORTANCE_DEFAULT);
|
|
||||||
channel.setShowBadge(false);
|
|
||||||
channel.setDescription("桃夭系统通知");
|
|
||||||
final NotificationManager notificationManager = this.getSystemService(NotificationManager.class);
|
final NotificationManager notificationManager = this.getSystemService(NotificationManager.class);
|
||||||
notificationManager.createNotificationChannel(channel);
|
final NotificationChannel notificationChannel = new NotificationChannel(TAOYAO, "桃夭通知", NotificationManager.IMPORTANCE_DEFAULT);
|
||||||
|
notificationChannel.setShowBadge(false);
|
||||||
|
notificationChannel.setDescription("桃夭通知");
|
||||||
|
notificationManager.createNotificationChannel(notificationChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanAllNotification() {
|
/**
|
||||||
final NotificationManager notificationManager = this.getSystemService(NotificationManager.class);
|
* @param mainHandler MainHandler
|
||||||
notificationManager.cancelAll();
|
*/
|
||||||
|
public static final void setMainHandler(Handler mainHandler) {
|
||||||
|
MediaService.mainHandler = mainHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,12 +87,13 @@ public class SettingsActivity extends AppCompatActivity {
|
|||||||
editor.putString("settings.username", username);
|
editor.putString("settings.username", username);
|
||||||
editor.putString("settings.password", password);
|
editor.putString("settings.password", password);
|
||||||
editor.commit();
|
editor.commit();
|
||||||
// 重连
|
// 重连信令
|
||||||
final Intent intent = new Intent(this, MediaService.class);
|
final Intent serviceIntent = new Intent(this, MediaService.class);
|
||||||
intent.setAction(MediaService.Action.RECONNECT.name());
|
serviceIntent.setAction(MediaService.Action.RECONNECT.name());
|
||||||
this.startService(intent);
|
this.startService(serviceIntent);
|
||||||
// 返回预览页面
|
// 预览页面
|
||||||
this.startActivity(new Intent(this, MainActivity.class));
|
final Intent activityIntent = new Intent(this, MainActivity.class);
|
||||||
|
this.startActivity(activityIntent);
|
||||||
// 结束
|
// 结束
|
||||||
this.finish();
|
this.finish();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public class TaoyaoReceiver extends BroadcastReceiver {
|
|||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
Log.i(TaoyaoReceiver.class.getSimpleName(), "onReceive:" + intent.getAction());
|
Log.i(TaoyaoReceiver.class.getSimpleName(), "onReceive:" + intent.getAction());
|
||||||
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
|
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
|
||||||
this.launchPreview(context);
|
this.bootTaoyao(context);
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,11 +26,11 @@ public class TaoyaoReceiver extends BroadcastReceiver {
|
|||||||
*
|
*
|
||||||
* @param context 上下文
|
* @param context 上下文
|
||||||
*/
|
*/
|
||||||
private void launchPreview(Context context) {
|
private void bootTaoyao(Context context) {
|
||||||
final Intent intent = new Intent(context, MediaService.class);
|
final Intent serviceIntent = new Intent(context, MediaService.class);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
intent.setAction(MediaService.Action.LAUNCH.name());
|
serviceIntent.setAction(MediaService.Action.BOOT.name());
|
||||||
context.startForegroundService(intent);
|
context.startForegroundService(serviceIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources>
|
||||||
|
|
||||||
<style name="Theme.Taoyao" parent="Theme.MaterialComponents.Light.DarkActionBar">
|
<style name="Theme.Taoyao" parent="Theme.MaterialComponents.Light.DarkActionBar">
|
||||||
<item name="colorPrimary">@color/purple_500</item>
|
<item name="colorPrimary">@color/purple_500</item>
|
||||||
|
|||||||
@@ -210,6 +210,7 @@ public final class MediaManager {
|
|||||||
return
|
return
|
||||||
this.taoyao != null &&
|
this.taoyao != null &&
|
||||||
this.context != null &&
|
this.context != null &&
|
||||||
|
this.mainHandler != null &&
|
||||||
this.mediaProperties != null;
|
this.mediaProperties != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,6 +245,7 @@ public final class MediaManager {
|
|||||||
* @param iFrameInterval 关键帧频率
|
* @param iFrameInterval 关键帧频率
|
||||||
* @param imagePath 图片保存路径
|
* @param imagePath 图片保存路径
|
||||||
* @param videoPath 视频保存路径
|
* @param videoPath 视频保存路径
|
||||||
|
* @param tts 是否加载TTS
|
||||||
* @param watermark 水印信息
|
* @param watermark 水印信息
|
||||||
* @param videoSourceType 视频来源类型
|
* @param videoSourceType 视频来源类型
|
||||||
*/
|
*/
|
||||||
@@ -251,7 +253,7 @@ public final class MediaManager {
|
|||||||
Handler mainHandler, Context context,
|
Handler mainHandler, Context context,
|
||||||
int imageQuantity, String audioQuantity, String videoQuantity,
|
int imageQuantity, String audioQuantity, String videoQuantity,
|
||||||
int channelCount, int iFrameInterval,
|
int channelCount, int iFrameInterval,
|
||||||
String imagePath, String videoPath,
|
String imagePath, String videoPath, boolean tts,
|
||||||
String watermark, VideoSourceType videoSourceType
|
String watermark, VideoSourceType videoSourceType
|
||||||
) {
|
) {
|
||||||
this.mainHandler = mainHandler;
|
this.mainHandler = mainHandler;
|
||||||
@@ -265,6 +267,9 @@ public final class MediaManager {
|
|||||||
this.videoPath = videoPath;
|
this.videoPath = videoPath;
|
||||||
this.watermark = watermark;
|
this.watermark = watermark;
|
||||||
this.videoSourceType = videoSourceType;
|
this.videoSourceType = videoSourceType;
|
||||||
|
if(tts) {
|
||||||
|
this.initTTS(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -274,7 +279,7 @@ public final class MediaManager {
|
|||||||
this.taoyao = taoyao;
|
this.taoyao = taoyao;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initTTS(Context context) {
|
private void initTTS(Context context) {
|
||||||
if(this.textToSpeech != null) {
|
if(this.textToSpeech != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,66 +7,66 @@ package com.acgist.taoyao.media.config;
|
|||||||
*/
|
*/
|
||||||
public class MediaAudioProperties {
|
public class MediaAudioProperties {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 音频格式
|
* 音频格式
|
||||||
*
|
*
|
||||||
* @author acgist
|
* @author acgist
|
||||||
*/
|
*/
|
||||||
public enum Format {
|
public enum Format {
|
||||||
|
|
||||||
G722,
|
G722,
|
||||||
PCMA,
|
PCMA,
|
||||||
PCMU,
|
PCMU,
|
||||||
OPUS;
|
OPUS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式:G722|PCMA|PCMU|OPUS
|
* 格式:G722|PCMA|PCMU|OPUS
|
||||||
*/
|
*/
|
||||||
private Format format;
|
private Format format;
|
||||||
/**
|
/**
|
||||||
* 比特率:96|128|256
|
* 比特率:96|128|256
|
||||||
*/
|
*/
|
||||||
private Integer bitrate;
|
private Integer bitrate;
|
||||||
/**
|
/**
|
||||||
* 采样位数:8|16|32
|
* 采样位数:8|16|32
|
||||||
*/
|
*/
|
||||||
private Integer sampleSize;
|
private Integer sampleSize;
|
||||||
/**
|
/**
|
||||||
* 采样率:8000|16000|32000|48000
|
* 采样率:8000|16000|32000|48000
|
||||||
*/
|
*/
|
||||||
private Integer sampleRate;
|
private Integer sampleRate;
|
||||||
|
|
||||||
public Format getFormat() {
|
public Format getFormat() {
|
||||||
return this.format;
|
return this.format;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFormat(Format format) {
|
public void setFormat(Format format) {
|
||||||
this.format = format;
|
this.format = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getBitrate() {
|
public Integer getBitrate() {
|
||||||
return bitrate;
|
return bitrate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBitrate(Integer bitrate) {
|
public void setBitrate(Integer bitrate) {
|
||||||
this.bitrate = bitrate;
|
this.bitrate = bitrate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getSampleSize() {
|
public Integer getSampleSize() {
|
||||||
return this.sampleSize;
|
return this.sampleSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSampleSize(Integer sampleSize) {
|
public void setSampleSize(Integer sampleSize) {
|
||||||
this.sampleSize = sampleSize;
|
this.sampleSize = sampleSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getSampleRate() {
|
public Integer getSampleRate() {
|
||||||
return this.sampleRate;
|
return this.sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSampleRate(Integer sampleRate) {
|
public void setSampleRate(Integer sampleRate) {
|
||||||
this.sampleRate = sampleRate;
|
this.sampleRate = sampleRate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,93 +7,93 @@ package com.acgist.taoyao.media.config;
|
|||||||
*/
|
*/
|
||||||
public class MediaVideoProperties {
|
public class MediaVideoProperties {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 视频格式
|
* 视频格式
|
||||||
*
|
*
|
||||||
* @author acgist
|
* @author acgist
|
||||||
*/
|
*/
|
||||||
public enum Format {
|
public enum Format {
|
||||||
|
|
||||||
VP8,
|
VP8,
|
||||||
VP9,
|
VP9,
|
||||||
H264,
|
H264,
|
||||||
H265;
|
H265;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式:VP8|VP9|H264|H265
|
* 格式:VP8|VP9|H264|H265
|
||||||
*/
|
*/
|
||||||
private Format format;
|
private Format format;
|
||||||
/**
|
/**
|
||||||
* 码率:600|1200|1500|1800
|
* 码率:600|1200|1500|1800
|
||||||
* 码率影响画质
|
* 码率影响画质
|
||||||
*/
|
*/
|
||||||
private Integer bitrate;
|
private Integer bitrate;
|
||||||
/**
|
/**
|
||||||
* 帧率:15|18|20|24|30|45
|
* 帧率:15|18|20|24|30|45
|
||||||
* 帧率影响流畅
|
* 帧率影响流畅
|
||||||
*/
|
*/
|
||||||
private Integer frameRate;
|
private Integer frameRate;
|
||||||
/**
|
/**
|
||||||
* 分辨率:4096*2160|2560*1440|1920*1080|1280*720|720*480
|
* 分辨率:4096*2160|2560*1440|1920*1080|1280*720|720*480
|
||||||
* 分辨率影响画面大小
|
* 分辨率影响画面大小
|
||||||
*/
|
*/
|
||||||
private String resolution;
|
private String resolution;
|
||||||
/**
|
/**
|
||||||
* 宽度:4096|2560|1920|1280|720
|
* 宽度:4096|2560|1920|1280|720
|
||||||
*/
|
*/
|
||||||
private Integer width;
|
private Integer width;
|
||||||
/**
|
/**
|
||||||
* 高度:2160|1440|1080|720|480
|
* 高度:2160|1440|1080|720|480
|
||||||
*/
|
*/
|
||||||
private Integer height;
|
private Integer height;
|
||||||
|
|
||||||
public Format getFormat() {
|
public Format getFormat() {
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFormat(Format format) {
|
public void setFormat(Format format) {
|
||||||
this.format = format;
|
this.format = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getBitrate() {
|
public Integer getBitrate() {
|
||||||
return bitrate;
|
return bitrate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBitrate(Integer bitrate) {
|
public void setBitrate(Integer bitrate) {
|
||||||
this.bitrate = bitrate;
|
this.bitrate = bitrate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getFrameRate() {
|
public Integer getFrameRate() {
|
||||||
return frameRate;
|
return frameRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFrameRate(Integer frameRate) {
|
public void setFrameRate(Integer frameRate) {
|
||||||
this.frameRate = frameRate;
|
this.frameRate = frameRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getResolution() {
|
public String getResolution() {
|
||||||
return resolution;
|
return resolution;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResolution(String resolution) {
|
public void setResolution(String resolution) {
|
||||||
this.resolution = resolution;
|
this.resolution = resolution;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getWidth() {
|
public Integer getWidth() {
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWidth(Integer width) {
|
public void setWidth(Integer width) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getHeight() {
|
public Integer getHeight() {
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHeight(Integer height) {
|
public void setHeight(Integer height) {
|
||||||
this.height = height;
|
this.height = height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ import java.util.List;
|
|||||||
public class WebrtcProperties {
|
public class WebrtcProperties {
|
||||||
|
|
||||||
private Boolean encrypt;
|
private Boolean encrypt;
|
||||||
private WebrtcStunProperties[] stun;
|
private WebrtcStunProperties[] stun;
|
||||||
private WebrtcTurnProperties[] turn;
|
private WebrtcTurnProperties[] turn;
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public List<PeerConnection.IceServer> getIceServers() {
|
public List<PeerConnection.IceServer> getIceServers() {
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* 音频默认配置
|
* 音频默认配置
|
||||||
|
* TODO:MediaStreamTrack.applyConstraints()
|
||||||
|
* 播放音量、采集音量
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings
|
||||||
*/
|
*/
|
||||||
const defaultAudioConfig = {
|
const defaultAudioConfig = {
|
||||||
// 设备
|
// 设备
|
||||||
|
|||||||
Reference in New Issue
Block a user