[*] 依赖
This commit is contained in:
@@ -9,14 +9,19 @@ import android.os.Message;
|
|||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
|
import android.view.SurfaceView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
import com.acgist.taoyao.client.databinding.ActivityMainBinding;
|
import com.acgist.taoyao.client.databinding.ActivityMainBinding;
|
||||||
|
import com.acgist.taoyao.config.Config;
|
||||||
|
import com.acgist.taoyao.media.MediaManager;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@@ -25,7 +30,7 @@ import java.io.Serializable;
|
|||||||
*
|
*
|
||||||
* @author acgist
|
* @author acgist
|
||||||
*/
|
*/
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity implements Serializable {
|
||||||
|
|
||||||
private MainHandler mainHandler;
|
private MainHandler mainHandler;
|
||||||
private ActivityMainBinding binding;
|
private ActivityMainBinding binding;
|
||||||
@@ -96,6 +101,9 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
if(!allGranted) {
|
if(!allGranted) {
|
||||||
Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
MediaManager.getInstance().init(this.getApplicationContext());
|
||||||
|
MediaManager.getInstance().initAudio();
|
||||||
|
MediaManager.getInstance().initVideo();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -111,7 +119,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
Log.i(MainActivity.class.getSimpleName(), "拉起媒体服务");
|
Log.i(MainActivity.class.getSimpleName(), "拉起媒体服务");
|
||||||
final Intent intent = new Intent(this, MediaService.class);
|
final Intent intent = new Intent(this, MediaService.class);
|
||||||
if(this.mainHandler == null) {
|
if(this.mainHandler == null) {
|
||||||
this.mainHandler = new MainHandler();
|
this.mainHandler = new MainHandler(this);
|
||||||
}
|
}
|
||||||
intent.setAction(MediaService.Action.CONNECT.name());
|
intent.setAction(MediaService.Action.CONNECT.name());
|
||||||
intent.putExtra("mainHandler", this.mainHandler);
|
intent.putExtra("mainHandler", this.mainHandler);
|
||||||
@@ -136,14 +144,52 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
*
|
*
|
||||||
* @author acgist
|
* @author acgist
|
||||||
*/
|
*/
|
||||||
private static class MainHandler extends Handler implements Serializable {
|
public static class MainHandler extends Handler implements Serializable {
|
||||||
|
|
||||||
|
private final MainActivity mainActivity;
|
||||||
|
|
||||||
|
public MainHandler(MainActivity mainActivity) {
|
||||||
|
this.mainActivity = mainActivity;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(@NonNull Message message) {
|
public void handleMessage(@NonNull Message message) {
|
||||||
super.handleMessage(message);
|
super.handleMessage(message);
|
||||||
Log.d(MainActivity.class.getSimpleName(), "Handler消息:" + message.what + " - " + message.obj);
|
Log.d(MainHandler.class.getSimpleName(), "Handler消息:" + message.what + " - " + message.obj);
|
||||||
|
switch(message.what) {
|
||||||
|
case Config.WHAT_SCREEN_CAPTURE -> this.mainActivity.screenCapture(message);
|
||||||
|
case Config.WHAT_NEW_CLIENT_VIDEO -> this.mainActivity.newClientVideo(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 屏幕捕获
|
||||||
|
*
|
||||||
|
* @param message 消息
|
||||||
|
*/
|
||||||
|
private void screenCapture(Message message) {
|
||||||
|
final ActivityResultLauncher<Intent> activityResultLauncher = this.registerForActivityResult(
|
||||||
|
new ActivityResultContracts.StartActivityForResult(),
|
||||||
|
result -> {
|
||||||
|
if(result.getResultCode() == RESULT_OK) {
|
||||||
|
Log.i(MediaManager.class.getSimpleName(), "开始屏幕捕获");
|
||||||
|
message.getCallback().run();
|
||||||
|
} else {
|
||||||
|
Log.w(MainActivity.class.getSimpleName(), "屏幕捕获失败:" + result.getResultCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
activityResultLauncher.launch((Intent) message.obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新建用户视频
|
||||||
|
*
|
||||||
|
* @param message 消息
|
||||||
|
*/
|
||||||
|
private void newClientVideo(Message message) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -27,6 +27,7 @@ public class MediaService extends Service {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("taoyao");
|
System.loadLibrary("taoyao");
|
||||||
|
System.loadLibrary("jingle_peerconnection_so");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ android {
|
|||||||
"-DLIBWEBRTC_BINARY_PATH=" + WEBRTC_LIB_PATH,
|
"-DLIBWEBRTC_BINARY_PATH=" + WEBRTC_LIB_PATH,
|
||||||
"-DMEDIASOUPCLIENT_BUILD_TESTS=OFF",
|
"-DMEDIASOUPCLIENT_BUILD_TESTS=OFF",
|
||||||
"-DMEDIASOUPCLIENT_LOG_TRACE=OFF",
|
"-DMEDIASOUPCLIENT_LOG_TRACE=OFF",
|
||||||
"-DMEDIASOUPCLIENT_LOG_DEV=OFF"
|
"-DMEDIASOUPCLIENT_LOG_DEV=OFF",
|
||||||
|
"-DANDROID_STL=c++_shared"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,10 +45,15 @@ android {
|
|||||||
version '3.22.1'
|
version '3.22.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
jniLibs.srcDirs = ["libs"]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.a', '*.so', '*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
||||||
implementation 'org.apache.commons:commons-collections4:4.4'
|
implementation 'org.apache.commons:commons-collections4:4.4'
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
|
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
|||||||
|
package com.acgist.taoyao.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置
|
||||||
|
*
|
||||||
|
* @author acgist
|
||||||
|
*/
|
||||||
|
public class Config {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 屏幕捕获
|
||||||
|
*/
|
||||||
|
public static final int WHAT_SCREEN_CAPTURE = 1000;
|
||||||
|
/**
|
||||||
|
* 新建用户视频
|
||||||
|
*/
|
||||||
|
public static final int WHAT_NEW_CLIENT_VIDEO = 1001;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,12 +1,16 @@
|
|||||||
package com.acgist.taoyao.media;
|
package com.acgist.taoyao.media;
|
||||||
|
|
||||||
|
import java.util.logging.Handler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 房间终端
|
* 房间本地终端
|
||||||
* 使用NDK + Mediasoup实现多人会话
|
|
||||||
*
|
*
|
||||||
* @author acgist
|
* @author acgist
|
||||||
*/
|
*/
|
||||||
public class LocalClient {
|
public class LocalClient extends RoomClient {
|
||||||
|
|
||||||
|
public LocalClient(String name, String clientId, Handler handler) {
|
||||||
|
super(name, clientId, handler);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
package com.acgist.taoyao.media;
|
package com.acgist.taoyao.media;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.media.projection.MediaProjection;
|
||||||
|
import android.media.projection.MediaProjectionManager;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.acgist.taoyao.config.Config;
|
||||||
|
|
||||||
import org.webrtc.AudioSource;
|
import org.webrtc.AudioSource;
|
||||||
import org.webrtc.AudioTrack;
|
import org.webrtc.AudioTrack;
|
||||||
import org.webrtc.Camera2Enumerator;
|
import org.webrtc.Camera2Enumerator;
|
||||||
@@ -12,6 +19,7 @@ import org.webrtc.EglBase;
|
|||||||
import org.webrtc.MediaConstraints;
|
import org.webrtc.MediaConstraints;
|
||||||
import org.webrtc.MediaStream;
|
import org.webrtc.MediaStream;
|
||||||
import org.webrtc.PeerConnectionFactory;
|
import org.webrtc.PeerConnectionFactory;
|
||||||
|
import org.webrtc.ScreenCapturerAndroid;
|
||||||
import org.webrtc.SurfaceTextureHelper;
|
import org.webrtc.SurfaceTextureHelper;
|
||||||
import org.webrtc.SurfaceViewRenderer;
|
import org.webrtc.SurfaceViewRenderer;
|
||||||
import org.webrtc.VideoCapturer;
|
import org.webrtc.VideoCapturer;
|
||||||
@@ -36,6 +44,8 @@ public class MediaManager {
|
|||||||
*/
|
*/
|
||||||
public enum Type {
|
public enum Type {
|
||||||
|
|
||||||
|
// 文件共享
|
||||||
|
FILE,
|
||||||
// 后置摄像头
|
// 后置摄像头
|
||||||
BACK,
|
BACK,
|
||||||
// 前置摄像头
|
// 前置摄像头
|
||||||
@@ -43,12 +53,33 @@ public class MediaManager {
|
|||||||
// 屏幕共享
|
// 屏幕共享
|
||||||
SCREEN;
|
SCREEN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 是否摄像头
|
||||||
|
*/
|
||||||
|
public boolean isCamera() {
|
||||||
|
return this == BACK || this == FRONT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final MediaManager INSTANCE = new MediaManager();
|
||||||
|
|
||||||
|
private MediaManager() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final MediaManager getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 视频类型
|
* 视频类型
|
||||||
*/
|
*/
|
||||||
private Type type;
|
private Type type;
|
||||||
|
/**
|
||||||
|
* Handler
|
||||||
|
*/
|
||||||
|
private Handler handler;
|
||||||
/**
|
/**
|
||||||
* 上下文
|
* 上下文
|
||||||
*/
|
*/
|
||||||
@@ -58,21 +89,16 @@ public class MediaManager {
|
|||||||
*/
|
*/
|
||||||
private MediaStream mediaStream;
|
private MediaStream mediaStream;
|
||||||
/**
|
/**
|
||||||
* 屏幕捕获
|
* 视频捕获
|
||||||
|
* FileVideoCapturer
|
||||||
|
* CameraVideoCapturer
|
||||||
|
* ScreenCapturerAndroid
|
||||||
*/
|
*/
|
||||||
private VideoCapturer videoCapturer;
|
private VideoCapturer videoCapturer;
|
||||||
/**
|
|
||||||
* 摄像头捕获
|
|
||||||
*/
|
|
||||||
private CameraVideoCapturer cameraVideoCapturer;
|
|
||||||
/**
|
/**
|
||||||
* Peer连接工厂
|
* Peer连接工厂
|
||||||
*/
|
*/
|
||||||
private PeerConnectionFactory peerConnectionFactory;
|
private PeerConnectionFactory peerConnectionFactory;
|
||||||
/**
|
|
||||||
* 预览
|
|
||||||
*/
|
|
||||||
private SurfaceViewRenderer previewView;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// 设置采样
|
// 设置采样
|
||||||
@@ -85,8 +111,17 @@ public class MediaManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载媒体流
|
* 加载媒体流
|
||||||
|
*
|
||||||
|
* @param context 上下文
|
||||||
*/
|
*/
|
||||||
public void init() {
|
public void init(Context context) {
|
||||||
|
this.type = Type.BACK;
|
||||||
|
this.context = context;
|
||||||
|
PeerConnectionFactory.initialize(
|
||||||
|
PeerConnectionFactory.InitializationOptions.builder(this.context)
|
||||||
|
.setEnableInternalTracer(true)
|
||||||
|
.createInitializationOptions()
|
||||||
|
);
|
||||||
this.peerConnectionFactory = PeerConnectionFactory.builder().createPeerConnectionFactory();
|
this.peerConnectionFactory = PeerConnectionFactory.builder().createPeerConnectionFactory();
|
||||||
this.mediaStream = this.peerConnectionFactory.createLocalMediaStream("ARDAMS");
|
this.mediaStream = this.peerConnectionFactory.createLocalMediaStream("ARDAMS");
|
||||||
}
|
}
|
||||||
@@ -104,11 +139,10 @@ public class MediaManager {
|
|||||||
}
|
}
|
||||||
this.type = type;
|
this.type = type;
|
||||||
Log.i(MediaManager.class.getSimpleName(), "设置视频来源:" + type);
|
Log.i(MediaManager.class.getSimpleName(), "设置视频来源:" + type);
|
||||||
if(this.type == Type.SCREEN || type == Type.SCREEN) {
|
if(this.type.isCamera() && type.isCamera()) {
|
||||||
this.initVideo();
|
|
||||||
} else {
|
|
||||||
// TODO:测试是否需要完全重置
|
// TODO:测试是否需要完全重置
|
||||||
this.cameraVideoCapturer.switchCamera(new CameraVideoCapturer.CameraSwitchHandler() {
|
final CameraVideoCapturer cameraVideoCapturer = (CameraVideoCapturer) this.videoCapturer;
|
||||||
|
cameraVideoCapturer.switchCamera(new CameraVideoCapturer.CameraSwitchHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void onCameraSwitchDone(boolean success) {
|
public void onCameraSwitchDone(boolean success) {
|
||||||
}
|
}
|
||||||
@@ -116,13 +150,15 @@ public class MediaManager {
|
|||||||
public void onCameraSwitchError(String message) {
|
public void onCameraSwitchError(String message) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
this.initVideo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载音频
|
* 加载音频
|
||||||
*/
|
*/
|
||||||
private void initAudio() {
|
public void initAudio() {
|
||||||
// 关闭音频
|
// 关闭音频
|
||||||
this.closeAudioTrack();
|
this.closeAudioTrack();
|
||||||
// 加载音频
|
// 加载音频
|
||||||
@@ -137,57 +173,68 @@ public class MediaManager {
|
|||||||
/**
|
/**
|
||||||
* 加载视频
|
* 加载视频
|
||||||
*/
|
*/
|
||||||
private void initVideo() {
|
public void initVideo() {
|
||||||
this.closeVideoTrack();
|
this.closeVideoTrack();
|
||||||
if(this.cameraVideoCapturer != null) {
|
if(this.videoCapturer != null) {
|
||||||
this.cameraVideoCapturer.dispose();
|
this.videoCapturer.dispose();
|
||||||
}
|
}
|
||||||
final CameraEnumerator cameraEnumerator = new Camera2Enumerator(this.context);
|
if(this.type.isCamera()) {
|
||||||
final String[] names = cameraEnumerator.getDeviceNames();
|
final CameraEnumerator cameraEnumerator = new Camera2Enumerator(this.context);
|
||||||
for(String name : names) {
|
final String[] names = cameraEnumerator.getDeviceNames();
|
||||||
if(this.type == Type.FRONT && cameraEnumerator.isFrontFacing(name)) {
|
for(String name : names) {
|
||||||
Log.i(MediaManager.class.getSimpleName(), "加载前置摄像头:" + name);
|
if(this.type == Type.FRONT && cameraEnumerator.isFrontFacing(name)) {
|
||||||
this.cameraVideoCapturer = cameraEnumerator.createCapturer(name, new MediaCameraEventsHandler());
|
Log.i(MediaManager.class.getSimpleName(), "加载视频(前置摄像头):" + name);
|
||||||
} else if(this.type == Type.BACK && cameraEnumerator.isBackFacing(name)) {
|
this.videoCapturer = cameraEnumerator.createCapturer(name, new MediaCameraEventsHandler());
|
||||||
Log.i(MediaManager.class.getSimpleName(), "加载后置摄像头:" + name);
|
} else if(this.type == Type.BACK && cameraEnumerator.isBackFacing(name)) {
|
||||||
this.cameraVideoCapturer = cameraEnumerator.createCapturer(name, new MediaCameraEventsHandler());
|
Log.i(MediaManager.class.getSimpleName(), "加载视频(后置摄像头):" + name);
|
||||||
} else {
|
this.videoCapturer = cameraEnumerator.createCapturer(name, new MediaCameraEventsHandler());
|
||||||
Log.i(MediaManager.class.getSimpleName(), "忽略摄像头:" + name);
|
} else {
|
||||||
|
Log.d(MediaManager.class.getSimpleName(), "忽略摄像头:" + name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if(this.type == Type.FILE) {
|
||||||
|
Log.i(MediaManager.class.getSimpleName(), "加载视频(文件)");
|
||||||
|
} else if(this.type == Type.SCREEN) {
|
||||||
|
Log.i(MediaManager.class.getSimpleName(), "加载视频(录屏)");
|
||||||
|
final MediaProjectionManager mediaProjectionManager = this.context.getSystemService(MediaProjectionManager.class);
|
||||||
|
final Intent intent = mediaProjectionManager.createScreenCaptureIntent();
|
||||||
|
final Message message = Message.obtain(this.handler, () -> {
|
||||||
|
this.videoCapturer = new ScreenCapturerAndroid(intent, new MediaProjection.Callback() {
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
Log.i(MediaManager.class.getSimpleName(), "停止屏幕捕获");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
message.obj = intent;
|
||||||
|
message.what = Config.WHAT_SCREEN_CAPTURE;
|
||||||
|
this.handler.sendMessage(message);
|
||||||
|
// this.handler.dispatchMessage(message);
|
||||||
}
|
}
|
||||||
|
this.initVideoTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载视频
|
* 加载视频
|
||||||
*/
|
*/
|
||||||
private void initVideoTrack() {
|
private void initVideoTrack() {
|
||||||
SurfaceTextureHelper surfaceTextureHelper = null;
|
|
||||||
// 设置预览
|
// 设置预览
|
||||||
if(this.previewView != null) {
|
final SurfaceViewRenderer surfaceViewRenderer = new SurfaceViewRenderer(this.context);
|
||||||
final EglBase eglBase = EglBase.create();
|
surfaceViewRenderer.setMirror(true);
|
||||||
surfaceTextureHelper = SurfaceTextureHelper.create("MediaVideoThread", eglBase.getEglBaseContext());
|
surfaceViewRenderer.setEnableHardwareScaler(true);
|
||||||
this.previewView.setMirror(true);
|
// 加载视频
|
||||||
this.previewView.setEnableHardwareScaler(true);
|
final EglBase eglBase = EglBase.create();
|
||||||
}
|
final SurfaceTextureHelper surfaceTextureHelper = SurfaceTextureHelper.create("MediaVideoThread", eglBase.getEglBaseContext());
|
||||||
// 是否捕获屏幕
|
final VideoSource videoSource = this.peerConnectionFactory.createVideoSource(this.videoCapturer.isScreencast());
|
||||||
final boolean screen = this.type == Type.SCREEN;
|
this.videoCapturer.initialize(surfaceTextureHelper, this.context, videoSource.getCapturerObserver());
|
||||||
final VideoSource videoSource = this.peerConnectionFactory.createVideoSource(screen);
|
this.videoCapturer.startCapture(640, 480, 30);
|
||||||
if(screen) {
|
|
||||||
Log.i(MediaManager.class.getSimpleName(), "捕获屏幕");
|
|
||||||
} else {
|
|
||||||
Log.i(MediaManager.class.getSimpleName(), "捕获摄像头");
|
|
||||||
this.cameraVideoCapturer.initialize(surfaceTextureHelper, this.context, videoSource.getCapturerObserver());
|
|
||||||
this.cameraVideoCapturer.startCapture(640, 480, 30);
|
|
||||||
}
|
|
||||||
final VideoTrack videoTrack = this.peerConnectionFactory.createVideoTrack("ARDAMSv0", videoSource);
|
final VideoTrack videoTrack = this.peerConnectionFactory.createVideoTrack("ARDAMSv0", videoSource);
|
||||||
videoTrack.setEnabled(true);
|
videoTrack.setEnabled(true);
|
||||||
this.mediaStream.addTrack(videoTrack);
|
this.mediaStream.addTrack(videoTrack);
|
||||||
Log.i(MediaManager.class.getSimpleName(), "加载视频:" + videoTrack.id());
|
Log.i(MediaManager.class.getSimpleName(), "加载视频:" + videoTrack.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initPreview() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pauseAudio() {
|
public void pauseAudio() {
|
||||||
synchronized (this.mediaStream.audioTracks) {
|
synchronized (this.mediaStream.audioTracks) {
|
||||||
this.mediaStream.audioTracks.forEach(a -> a.setEnabled(false));
|
this.mediaStream.audioTracks.forEach(a -> a.setEnabled(false));
|
||||||
@@ -264,14 +311,17 @@ public class MediaManager {
|
|||||||
* 释放资源
|
* 释放资源
|
||||||
*/
|
*/
|
||||||
public void close() {
|
public void close() {
|
||||||
if(this.cameraVideoCapturer != null) {
|
if(this.videoCapturer != null) {
|
||||||
this.cameraVideoCapturer.dispose();
|
this.videoCapturer.dispose();
|
||||||
|
this.videoCapturer = null;
|
||||||
}
|
}
|
||||||
if(this.mediaStream != null) {
|
if(this.mediaStream != null) {
|
||||||
this.mediaStream.dispose();
|
this.mediaStream.dispose();
|
||||||
|
this.mediaStream = null;
|
||||||
}
|
}
|
||||||
if(this.peerConnectionFactory != null) {
|
if(this.peerConnectionFactory != null) {
|
||||||
this.peerConnectionFactory.dispose();
|
this.peerConnectionFactory.dispose();
|
||||||
|
this.peerConnectionFactory = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
package com.acgist.taoyao.media;
|
package com.acgist.taoyao.media;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 房间远程终端
|
||||||
|
*
|
||||||
|
* @author acgist
|
||||||
|
*/
|
||||||
public class RemoteClient {
|
public class RemoteClient {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.acgist.taoyao.media;
|
||||||
|
|
||||||
|
import org.webrtc.AudioTrack;
|
||||||
|
import org.webrtc.MediaStream;
|
||||||
|
import org.webrtc.VideoTrack;
|
||||||
|
|
||||||
|
import java.util.logging.Handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 房间终端
|
||||||
|
* 使用NDK + Mediasoup实现多人会话
|
||||||
|
*
|
||||||
|
* @author acgist
|
||||||
|
*/
|
||||||
|
public class RoomClient {
|
||||||
|
|
||||||
|
protected final String name;
|
||||||
|
protected final String clientId;
|
||||||
|
protected final Handler handler;
|
||||||
|
protected AudioTrack audioTrack;
|
||||||
|
protected VideoTrack videoTrack;
|
||||||
|
protected MediaStream mediaStream;
|
||||||
|
|
||||||
|
public RoomClient(String name, String clientId, Handler handler) {
|
||||||
|
this.name = name;
|
||||||
|
this.clientId = clientId;
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开预览
|
||||||
|
*/
|
||||||
|
private void preview() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user