From 6a21e3668cef4a6f150529eba991eb6e94fcabf5 Mon Sep 17 00:00:00 2001 From: acgist <289547414@qq.com> Date: Sat, 15 Apr 2023 15:23:54 +0800 Subject: [PATCH] [+] android github action --- .github/workflows/build.yml | 28 ++++++- .../acgist/taoyao/client/signal/Taoyao.java | 67 +++++++-------- .../com/acgist/taoyao/media/MediaManager.java | 82 +++++++++---------- .../taoyao/media/client/LocalClient.java | 3 +- .../taoyao/media/client/PhotographClient.java | 69 +++++++++------- .../taoyao/media/client/RecordClient.java | 5 ++ .../taoyao/media/client/RemoteClient.java | 3 +- .../taoyao/media/client/SessionClient.java | 3 +- taoyao-client-media/README.md | 5 ++ taoyao-signal-server/README.md | 5 -- 10 files changed, 147 insertions(+), 123 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f79b37d..b1fac08 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,7 @@ on: branches: [ master ] jobs: - taoyao-snail-server: + taoyao-signal-server: name: Build taoyao signal server strategy: matrix: @@ -13,9 +13,9 @@ jobs: runs-on: ${{ matrix.runs-on }} steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up JDK - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: java-version: 17 - name: Build with Maven @@ -61,4 +61,24 @@ jobs: # 不能直接运行 # npm run dev working-directory: ./taoyao-client-media - \ No newline at end of file + taoyao-client-android: + name: Build taoyao client android + strategy: + matrix: + runs-on: [ macos-latest, ubuntu-latest, windows-latest ] + runs-on: ${{ matrix.runs-on }} + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Set up JDK + uses: actions/setup-java@v3 + with: + java-version: 17 + - name: Setup Android SDK + uses: android-actions/setup-android@v2 + - name: Build with Gradle + if: runner.os != 'windows' + run: ./taoyao-client-android/taoyao/gradlew --no-daemon assembleRelease + - name: Build with Gradle + if: runner.os == 'windows' + run: ./taoyao-client-android/taoyao/gradlew.bat --no-daemon assembleRelease diff --git a/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/signal/Taoyao.java b/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/signal/Taoyao.java index e1ed1f6..6c1d72d 100644 --- a/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/signal/Taoyao.java +++ b/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/signal/Taoyao.java @@ -156,21 +156,21 @@ public final class Taoyao implements ITaoyao { */ private final Map requestMessage; /** - * 循环消息Handler + * 消息Handler */ - private final Handler loopMessageHandler; + private final Handler messageHandler; /** - * 循环消息线程 + * 消息线程 */ - private final HandlerThread loopMessageThread; + private final HandlerThread messageThread; /** - * 消息处理Handler + * 执行Handler */ - private final Handler executeMessageHandler; + private final Handler executeHandler; /** - * 消息处理线程 + * 执行线程 */ - private final HandlerThread executeMessageThread; + private final HandlerThread executeThread; /** * 心跳Handler */ @@ -224,15 +224,15 @@ public final class Taoyao implements ITaoyao { this.batteryManager = context.getSystemService(BatteryManager.class); this.locationManager = context.getSystemService(LocationManager.class); this.requestMessage = new ConcurrentHashMap<>(); - this.loopMessageThread = new HandlerThread("LoopMessageThread"); - this.loopMessageThread.setDaemon(true); - this.loopMessageThread.start(); - this.loopMessageHandler = new Handler(this.loopMessageThread.getLooper()); - this.loopMessageHandler.post(this::loopMessage); - this.executeMessageThread = new HandlerThread("ExecuteMessageThread"); - this.executeMessageThread.setDaemon(true); - this.executeMessageThread.start(); - this.executeMessageHandler = new Handler(this.executeMessageThread.getLooper()); + this.messageThread = new HandlerThread("MessageThread"); + this.messageThread.setDaemon(true); + this.messageThread.start(); + this.messageHandler = new Handler(this.messageThread.getLooper()); + this.messageHandler.post(this::connect); + this.executeThread = new HandlerThread("ExecuteThread"); + this.executeThread.setDaemon(true); + this.executeThread.start(); + this.executeHandler = new Handler(this.executeThread.getLooper()); this.heartbeatThread = new HandlerThread("HeartbeatThread"); this.heartbeatThread.setDaemon(true); this.heartbeatThread.start(); @@ -281,26 +281,20 @@ public final class Taoyao implements ITaoyao { // socket.setSoTimeout(this.timeout); this.socket.connect(new InetSocketAddress(this.host, this.port), this.timeout); if (this.socket.isConnected()) { + this.connect = true; this.input = this.socket.getInputStream(); this.output = this.socket.getOutputStream(); this.clientRegister(); - this.connect = true; this.taoyaoListener.onConnected(); - synchronized (this) { - this.notifyAll(); - } + this.messageHandler.post(this::pull); } else { this.connect = false; - synchronized (this) { - try { - this.wait(this.timeout); - } catch (InterruptedException e) { - Log.d(Taoyao.class.getSimpleName(), "信令等待异常", e); - } - } + this.messageHandler.postDelayed(this::connect, this.timeout); } } catch (Exception e) { Log.e(Taoyao.class.getSimpleName(), "连接信令异常:" + this.host + ":" + this.port, e); + this.connect = false; + this.messageHandler.postDelayed(this::connect, this.timeout); } return this.connect; } @@ -308,17 +302,13 @@ public final class Taoyao implements ITaoyao { /** * 循环读取信令消息 */ - private void loopMessage() { + private void pull() { int length = 0; short messageLength = 0; final byte[] bytes = new byte[1024]; final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024); - while (!this.close) { + while (!this.close && this.connect) { try { - // 重连 - while (!this.close && !this.connect) { - this.connect(); - } // 读取 while (!this.close && (length = this.input.read(bytes)) >= 0) { buffer.put(bytes, 0, length); @@ -362,6 +352,9 @@ public final class Taoyao implements ITaoyao { this.disconnect(); } } + if (!this.close && !this.connect) { + this.messageHandler.post(this::connect); + } } /** @@ -461,8 +454,8 @@ public final class Taoyao implements ITaoyao { this.close = true; this.disconnect(); this.heartbeatThread.quitSafely(); - this.loopMessageThread.quitSafely(); - this.executeMessageThread.quitSafely(); + this.messageThread.quitSafely(); + this.executeThread.quitSafely(); this.rooms.values().forEach(Room::close); this.sessionClients.values().forEach(SessionClient::close); } @@ -525,7 +518,7 @@ public final class Taoyao implements ITaoyao { request.notifyAll(); } } else { - this.executeMessageHandler.post(() -> this.dispatch(content, header, message)); + this.executeHandler.post(() -> this.dispatch(content, header, message)); } } diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/MediaManager.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/MediaManager.java index 610b2e0..7a2fe6f 100644 --- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/MediaManager.java +++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/MediaManager.java @@ -8,6 +8,7 @@ import android.media.projection.MediaProjection; import android.os.Handler; import android.os.Message; import android.util.Log; +import android.widget.Toast; import com.acgist.taoyao.media.client.PhotographClient; import com.acgist.taoyao.media.client.RecordClient; @@ -87,7 +88,13 @@ public final class MediaManager { * 视频质量 */ private String videoQuantity; + /** + * 通道数量 + */ private int channelCount; + /** + * 关键帧频率 + */ private int iFrameInterval; /** * 视频来源类型 @@ -220,10 +227,13 @@ public final class MediaManager { } /** - * @return 是否可用 + * @return 是否可用:所有配置加载完成 */ public boolean available() { - return this.mainHandler != null && this.context != null && this.taoyao != null; + return + this.taoyao != null && + this.context != null && + this.mediaProperties != null; } /** @@ -265,7 +275,8 @@ public final class MediaManager { */ public PeerConnectionFactory newClient(VideoSourceType videoSourceType) { synchronized (this) { - while(this.mediaProperties == null) { + while(!this.available()) { + Log.i(MediaManager.class.getSimpleName(), "等待配置"); try { this.wait(1000); } catch (InterruptedException e) { @@ -409,14 +420,14 @@ public final class MediaManager { // 高音过滤 mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googHighpassFilter", "true")); // mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googAudioMirroring", "false")); - // 自动增益 + // 自动增益:AGC mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googAutoGainControl", "true")); // mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googAutoGainControl2", "true")); - // 回声消除 + // 回声消除:AEC mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googEchoCancellation", "true")); // mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googEchoCancellation2", "true")); // mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googDAEchoCancellation", "true")); - // 噪音处理 + // 噪音处理:NS mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googNoiseSuppression", "true")); // mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googNoiseSuppression2", "true")); // mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googTypingNoiseDetection", "true")); @@ -545,11 +556,7 @@ public final class MediaManager { public void updateVideoConfig(MediaVideoProperties mediaVideoProperties) { this.mediaVideoProperties = mediaVideoProperties; if(this.videoCapturer != null) { - try { - this.videoCapturer.stopCapture(); - } catch (InterruptedException e) { - Log.e(MediaManager.class.getSimpleName(), "暂停视频捕获异常", e); - } + this.stopCapture("次码流", this.videoCapturer); this.videoCapturer.startCapture(this.mediaVideoProperties.getWidth(), this.mediaVideoProperties.getHeight(), this.mediaVideoProperties.getFrameRate()); } } @@ -615,11 +622,7 @@ public final class MediaManager { } this.shareClientCount--; if(this.shareClientCount <= 0) { - try { - this.videoCapturer.stopCapture(); - } catch (InterruptedException e) { - Log.e(MediaManager.class.getSimpleName(), "关闭视频捕获(次码流)异常", e); - } + this.stopCapture("次码流", this.videoCapturer); } } } @@ -627,24 +630,18 @@ public final class MediaManager { public String photograph() { synchronized (this) { String filepath; + final MediaVideoProperties mediaVideoProperties = this.mediaProperties.getVideos().get(this.videoQuantity); + final PhotographClient photographClient = new PhotographClient(this.imageQuantity, this.imagePath); if(this.clientCount <= 0) { - final MediaVideoProperties mediaVideoProperties = this.mediaProperties.getVideos().get(this.videoQuantity); - final PhotographClient photographClient = new PhotographClient(this.imageQuantity, this.imagePath); filepath = photographClient.photograph(mediaVideoProperties.getWidth(), mediaVideoProperties.getHeight(), VideoSourceType.BACK, this.context); - return filepath; - } - this.photographClient = new PhotographClient(this.imageQuantity, this.imagePath); - if(this.recordClient == null) { - final MediaVideoProperties mediaVideoProperties = this.mediaProperties.getVideos().get(this.videoQuantity); - this.recordVideoCapturer.startCapture(mediaVideoProperties.getWidth(), mediaVideoProperties.getHeight(), mediaVideoProperties.getFrameRate()); + } else if(this.recordClient != null) { + this.photographClient = photographClient; filepath = this.photographClient.waitForPhotograph(); - try { - this.recordVideoCapturer.stopCapture(); - } catch (InterruptedException e) { - Log.e(MediaManager.class.getSimpleName(), "关闭视频捕获(主码流)异常", e); - } } else { + this.photographClient = photographClient; + this.recordVideoCapturer.startCapture(mediaVideoProperties.getWidth(), mediaVideoProperties.getHeight(), PhotographClient.CAPTURER_SIZE); filepath = this.photographClient.waitForPhotograph(); + this.stopCapture("主码流", this.recordVideoCapturer); } this.photographClient = null; return filepath; @@ -663,9 +660,8 @@ public final class MediaManager { mediaVideoProperties.getBitrate(), mediaVideoProperties.getFrameRate(), this.iFrameInterval, mediaVideoProperties.getWidth(), mediaVideoProperties.getHeight(), this.videoPath, this.taoyao, this.mainHandler ); - this.newClient(VideoSourceType.BACK); - this.recordVideoCapturer.startCapture(mediaVideoProperties.getWidth(), mediaVideoProperties.getHeight(), mediaVideoProperties.getFrameRate()); this.recordClient.start(); + this.recordVideoCapturer.startCapture(mediaVideoProperties.getWidth(), mediaVideoProperties.getHeight(), mediaVideoProperties.getFrameRate()); return this.recordClient; } } @@ -677,16 +673,22 @@ public final class MediaManager { } else { this.recordClient.close(); this.recordClient = null; - try { - this.recordVideoCapturer.stopCapture(); - } catch (InterruptedException e) { - Log.e(MediaManager.class.getSimpleName(), "关闭视频捕获(主码流)异常", e); - } - this.closeClient(); + this.stopCapture("主码流", this.recordVideoCapturer); } } } + private void stopCapture(String name, VideoCapturer videoCapturer) { + if(this.videoCapturer == null) { + return; + } + try { + videoCapturer.stopCapture(); + } catch (InterruptedException e) { + Log.e(MediaManager.class.getSimpleName(), "关闭视频捕获异常:" + name, e); + } + } + /** * @param flag Config.WHAT_* * @param videoTrack 视频媒体流Track @@ -703,12 +705,10 @@ public final class MediaManager { surfaceViewRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL); // 硬件拉伸 surfaceViewRenderer.setEnableHardwareScaler(true); +// surfaceViewRenderer.setFpsReduction(); // 加载OpenSL ES surfaceViewRenderer.init(this.shareEglContext, null); - // 强制播放 - if(!videoTrack.enabled()) { - videoTrack.setEnabled(true); - } + // 添加播放 videoTrack.addSink(surfaceViewRenderer); }); // 页面加载 diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/LocalClient.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/LocalClient.java index 11e7e85..2111645 100644 --- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/LocalClient.java +++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/LocalClient.java @@ -62,10 +62,9 @@ public class LocalClient extends RoomClient { return; } ListUtils.getOnlyOne(this.mediaStream.videoTracks, videoTrack -> { + videoTrack.setEnabled(true); if(this.surfaceViewRenderer == null) { this.surfaceViewRenderer = this.mediaManager.buildSurfaceViewRenderer(Config.WHAT_NEW_LOCAL_VIDEO, videoTrack); - } else { - videoTrack.setEnabled(true); } return videoTrack; }); diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/PhotographClient.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/PhotographClient.java index 2c9dcb2..aa6a129 100644 --- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/PhotographClient.java +++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/PhotographClient.java @@ -2,6 +2,7 @@ package com.acgist.taoyao.media.client; import android.annotation.SuppressLint; import android.content.Context; +import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.ImageFormat; @@ -13,7 +14,6 @@ import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CameraManager; import android.hardware.camera2.CaptureRequest; -import android.hardware.camera2.TotalCaptureResult; import android.hardware.camera2.params.OutputConfiguration; import android.hardware.camera2.params.SessionConfiguration; import android.media.Image; @@ -36,7 +36,6 @@ import java.nio.ByteBuffer; import java.nio.file.Paths; import java.time.LocalDateTime; import java.util.List; -import java.util.concurrent.TimeUnit; /** * 拍照终端 @@ -45,6 +44,8 @@ import java.util.concurrent.TimeUnit; */ public class PhotographClient { + public static final int CAPTURER_SIZE = 1; + private final int quantity; private final String filename; private final String filepath; @@ -53,7 +54,6 @@ public class PhotographClient { private Surface surface; private ImageReader imageReader; private CameraDevice cameraDevice; - private CameraManager cameraManager; private CameraCaptureSession cameraCaptureSession; public PhotographClient(int quantity, String path) { @@ -65,8 +65,6 @@ public class PhotographClient { Log.i(RecordClient.class.getSimpleName(), "拍摄照片文件:" + this.filepath); } - // ================ 拉流拍照 ================ // - public String photograph(VideoFrame videoFrame) { if(this.wait) { this.wait = false; @@ -153,17 +151,31 @@ public class PhotographClient { return new YuvImage(nv21, ImageFormat.NV21, width, height, null); } - // ================ Camera2拍照 ================ // - @SuppressLint("MissingPermission") public String photograph(int width, int height, VideoSourceType type, Context context) { - this.cameraManager = context.getSystemService(CameraManager.class); - this.imageReader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1); + final CameraManager cameraManager = context.getSystemService(CameraManager.class); + this.imageReader = ImageReader.newInstance(width, height, ImageFormat.JPEG, PhotographClient.CAPTURER_SIZE); this.surface = this.imageReader.getSurface(); this.imageReader.setOnImageAvailableListener(this.imageAvailableListener, null); try { - final String cameraId = String.valueOf(type == VideoSourceType.BACK ? CameraCharacteristics.LENS_FACING_BACK : CameraCharacteristics.LENS_FACING_FRONT); - this.cameraManager.openCamera(cameraId, this.cameraDeviceStateCallback, null); + String cameraId = null; + final String[] cameraIdList = cameraManager.getCameraIdList(); + for (String id : cameraIdList) { + final CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(id); + if(cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_BACK && type == VideoSourceType.BACK) { + cameraId = id; + break; + } else if(cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT && type == VideoSourceType.FRONT) { + cameraId = id; + break; + } else { + } + } + if(cameraId == null) { + PhotographClient.this.closeCamera(); + return null; + } + cameraManager.openCamera(cameraId, this.cameraDeviceStateCallback, null); } catch (CameraAccessException e) { Log.e(PhotographClient.class.getSimpleName(), "拍照异常", e); PhotographClient.this.closeCamera(); @@ -171,25 +183,22 @@ public class PhotographClient { return this.filepath; } - private ImageReader.OnImageAvailableListener imageAvailableListener = new ImageReader.OnImageAvailableListener() { - @Override - public void onImageAvailable(ImageReader imageReader) { - final Image image = imageReader.acquireLatestImage(); - final ByteBuffer byteBuffer = image.getPlanes()[0].getBuffer(); - final byte[] bytes = new byte[byteBuffer.remaining()]; - byteBuffer.get(bytes); - final File file = new File(PhotographClient.this.filepath); - try ( - final OutputStream output = new FileOutputStream(file); - ) { - output.write(bytes,0,bytes.length); - } catch (IOException e) { - Log.e(PhotographClient.class.getSimpleName(), "拍照异常", e); - PhotographClient.this.closeCamera(); - } finally { - image.close(); - PhotographClient.this.closeCamera(); - } + private ImageReader.OnImageAvailableListener imageAvailableListener = (ImageReader imageReader) -> { + final Image image = imageReader.acquireLatestImage(); + final Image.Plane[] planes = image.getPlanes(); + final ByteBuffer byteBuffer = planes[0].getBuffer(); + final byte[] bytes = new byte[byteBuffer.remaining()]; + byteBuffer.get(bytes); + final File file = new File(PhotographClient.this.filepath); + try ( + final OutputStream output = new FileOutputStream(file); + ) { + output.write(bytes,0,bytes.length); + } catch (IOException e) { + Log.e(PhotographClient.class.getSimpleName(), "拍照异常", e); + } finally { + image.close(); + PhotographClient.this.closeCamera(); } }; diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/RecordClient.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/RecordClient.java index 11b4290..78c9f33 100644 --- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/RecordClient.java +++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/RecordClient.java @@ -1,5 +1,6 @@ package com.acgist.taoyao.media.client; +import android.media.AudioFormat; import android.media.MediaCodec; import android.media.MediaCodecInfo; import android.media.MediaFormat; @@ -152,6 +153,7 @@ public class RecordClient extends Client implements VideoSink, JavaAudioDeviceMo } Log.i(RecordClient.class.getSimpleName(), "录制视频文件:" + this.filepath); super.init(); + this.mediaManager.newClient(VideoSourceType.BACK); if ( this.audioThread == null || !this.audioThread.isAlive() || this.videoThread == null || !this.videoThread.isAlive() @@ -173,8 +175,10 @@ public class RecordClient extends Client implements VideoSink, JavaAudioDeviceMo // audioFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, this.sampleRate); // audioFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, this.channelCount); audioFormat.setInteger(MediaFormat.KEY_BIT_RATE, this.audioBitRate); +// audioFormat.setInteger(MediaFormat.KEY_BIT_RATE, AudioFormat.ENCODING_PCM_16BIT); audioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC); // audioFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR); +// audioFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1024 * 8 * 8); // 设置缓冲大小 this.audioCodec = MediaCodec.createEncoderByType(audioType); this.audioCodec.configure(audioFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); } catch (Exception e) { @@ -449,6 +453,7 @@ public class RecordClient extends Client implements VideoSink, JavaAudioDeviceMo file.delete(); } this.notifyAll(); + this.mediaManager.closeClient(); } } diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/RemoteClient.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/RemoteClient.java index ad14561..5378b2f 100644 --- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/RemoteClient.java +++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/RemoteClient.java @@ -54,10 +54,9 @@ public class RemoteClient extends RoomClient { .map(v -> (VideoTrack) v) .collect(Collectors.toList()), videoTrack -> { + videoTrack.setEnabled(true); if(this.surfaceViewRenderer == null) { this.surfaceViewRenderer = this.mediaManager.buildSurfaceViewRenderer(Config.WHAT_NEW_REMOTE_VIDEO, videoTrack); - } else { - videoTrack.setEnabled(true); } return videoTrack; } diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/SessionClient.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/SessionClient.java index 1443aed..489e32f 100644 --- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/SessionClient.java +++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/client/SessionClient.java @@ -233,10 +233,9 @@ public class SessionClient extends Client { return; } ListUtils.getOnlyOne(this.remoteMediaStream.videoTracks, videoTrack -> { + videoTrack.setEnabled(true); if(this.surfaceViewRenderer == null) { this.surfaceViewRenderer = this.mediaManager.buildSurfaceViewRenderer(Config.WHAT_NEW_REMOTE_VIDEO, videoTrack); - } else { - videoTrack.setEnabled(true); } return videoTrack; }); diff --git a/taoyao-client-media/README.md b/taoyao-client-media/README.md index 51e2cdb..6427a7d 100644 --- a/taoyao-client-media/README.md +++ b/taoyao-client-media/README.md @@ -69,3 +69,8 @@ make -C worker * [Kurento](https://github.com/Kurento/kurento-media-server) * [Medooze](https://github.com/medooze/media-server) * [Mediasoup](https://github.com/versatica/mediasoup) + +## 协议 + +* https://www.ortc.org +* https://www.webrtc.org diff --git a/taoyao-signal-server/README.md b/taoyao-signal-server/README.md index d6857fa..6f9c815 100644 --- a/taoyao-signal-server/README.md +++ b/taoyao-signal-server/README.md @@ -12,8 +12,3 @@ ## 信令格式 [信令格式](https://localhost:8888/protocol/list) - -## 协议 - -* https://www.ortc.org -* https://www.webrtc.org