diff --git a/taoyao-client-android/taoyao/client/src/main/AndroidManifest.xml b/taoyao-client-android/taoyao/client/src/main/AndroidManifest.xml index 8e3ded0..93be3b9 100644 --- a/taoyao-client-android/taoyao/client/src/main/AndroidManifest.xml +++ b/taoyao-client-android/taoyao/client/src/main/AndroidManifest.xml @@ -1,11 +1,6 @@ - - - - - diff --git a/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/MainActivity.java b/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/MainActivity.java index 1d82219..7ee5127 100644 --- a/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/MainActivity.java +++ b/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/MainActivity.java @@ -1,6 +1,8 @@ package com.acgist.taoyao.client; +import android.Manifest; import android.content.Intent; +import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -9,6 +11,7 @@ import android.util.Log; import android.view.Display; import android.view.View; import android.view.WindowManager; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; @@ -31,6 +34,8 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle bundle) { Log.i(MainActivity.class.getSimpleName(), "onCreate"); super.onCreate(bundle); + // 请求权限 + this.requestPermission(); // 启动点亮屏幕 this.setTurnScreenOn(true); // 锁屏显示屏幕 @@ -64,6 +69,35 @@ public class MainActivity extends AppCompatActivity { super.onDestroy(); } + /** + * 请求权限 + */ + private void requestPermission() { + final String[] permissions = new String[]{ + Manifest.permission.CAMERA, + Manifest.permission.INTERNET, + Manifest.permission.RECORD_AUDIO, + Manifest.permission.ACCESS_WIFI_STATE, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.RECEIVE_BOOT_COMPLETED, + Manifest.permission.WRITE_EXTERNAL_STORAGE + }; + boolean allGranted = true; + for (String permission : permissions) { + if(this.getApplicationContext().checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) { + Log.i(MediaService.class.getSimpleName(), "授权成功:" + permission); + } else { + allGranted = false; + Log.w(MediaService.class.getSimpleName(), "授权失败:" + permission); + } + } + if(!allGranted) { + Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show(); + } + } + /** * 拉起媒体服务 */ @@ -81,7 +115,6 @@ public class MainActivity extends AppCompatActivity { } intent.setAction(MediaService.Action.CONNECT.name()); intent.putExtra("mainHandler", this.mainHandler); - intent.setAction("connect"); this.startService(intent); } else { Log.w(MainActivity.class.getSimpleName(), "拉起媒体服务失败"); diff --git a/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/MediaService.java b/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/MediaService.java index efd2b98..a4d2a06 100644 --- a/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/MediaService.java +++ b/taoyao-client-android/taoyao/client/src/main/java/com/acgist/taoyao/client/MediaService.java @@ -1,9 +1,11 @@ package com.acgist.taoyao.client; +import android.Manifest; import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.location.LocationManager; import android.net.wifi.WifiManager; @@ -59,15 +61,15 @@ public class MediaService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(MediaService.class.getSimpleName(), "onStartCommand"); - if(Action.CONNECT.name().equals(intent.getAction())) { - if(this.taoyao == null) { + if (Action.CONNECT.name().equals(intent.getAction())) { + if (this.taoyao == null) { Log.d(MediaService.class.getSimpleName(), "打开信令连接"); this.mainHandler = (Handler) intent.getSerializableExtra("mainHandler"); this.connect(); } else { Log.d(MediaService.class.getSimpleName(), "信令已经连接"); } - } else if(Action.RECONNECT.name().equals(intent.getAction())) { + } else if (Action.RECONNECT.name().equals(intent.getAction())) { Log.d(MediaService.class.getSimpleName(), "重新连接信令"); this.connect(); } else { @@ -114,7 +116,7 @@ public class MediaService extends Service { } private synchronized void close() { - if(this.taoyao == null) { + if (this.taoyao == null) { return; } Toast.makeText(this.getApplicationContext(), "关闭信令", Toast.LENGTH_SHORT).show(); 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 52af01c..2c58c74 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 @@ -20,7 +20,7 @@ import com.acgist.taoyao.boot.model.MessageCode; import com.acgist.taoyao.boot.model.MessageCodeException; import com.acgist.taoyao.boot.utils.CloseableUtils; import com.acgist.taoyao.boot.utils.JSONUtils; -import com.acgist.taoyao.media.ClientRecorder; +import com.acgist.taoyao.media.MediaRecorder; import com.acgist.taoyao.client.utils.IdUtils; import org.apache.commons.lang3.ArrayUtils; @@ -499,7 +499,7 @@ public final class Taoyao { "signal", this.wifiSignal(), "battery", this.battery(), "charging", this.charging(), - "recording", ClientRecorder.getInstance().isActive() + "recording", MediaRecorder.getInstance().isActive() )); } @@ -530,7 +530,7 @@ public final class Taoyao { "signal", this.wifiSignal(), "battery", this.battery(), "charging", this.charging(), - "recording", ClientRecorder.getInstance().isActive() + "recording", MediaRecorder.getInstance().isActive() )); } diff --git a/taoyao-client-android/taoyao/client/src/main/res/values/settings.xml b/taoyao-client-android/taoyao/client/src/main/res/values/settings.xml index 6306e17..02201f5 100644 --- a/taoyao-client-android/taoyao/client/src/main/res/values/settings.xml +++ b/taoyao-client-android/taoyao/client/src/main/res/values/settings.xml @@ -12,4 +12,7 @@ DES 2SPWy+TF1zM= + + /taoyao/image + /taoyao/video \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/CMakeLists.txt b/taoyao-client-android/taoyao/media/CMakeLists.txt index 9958020..f52016f 100644 --- a/taoyao-client-android/taoyao/media/CMakeLists.txt +++ b/taoyao-client-android/taoyao/media/CMakeLists.txt @@ -25,10 +25,24 @@ set( set( SOURCE_FILES - ${SOURCE_DIR}/rtp.hpp - ${SOURCE_DIR}/rtp.cpp - ${SOURCE_DIR}/webrtc.hpp - ${SOURCE_DIR}/webrtc.cpp + ${SOURCE_DIR}/include/LocalClient.hpp + ${SOURCE_DIR}/include/MediaRecorder.hpp + ${SOURCE_DIR}/include/MediasoupClient.hpp + ${SOURCE_DIR}/include/P2PClient.hpp + ${SOURCE_DIR}/include/RemoteClient.hpp + ${SOURCE_DIR}/include/Room.hpp + ${SOURCE_DIR}/include/RtpAudioPublisher.hpp + ${SOURCE_DIR}/include/RtpClient.hpp + ${SOURCE_DIR}/include/RtpVideoPublisher.hpp + ${SOURCE_DIR}/media/LocalClient.cpp + ${SOURCE_DIR}/media/MediaRecorder.cpp + ${SOURCE_DIR}/media/P2PClient.cpp + ${SOURCE_DIR}/media/RemoteClient.cpp + ${SOURCE_DIR}/media/Room.cpp + ${SOURCE_DIR}/rtp/RtpAudioPublisher.cpp + ${SOURCE_DIR}/rtp/RtpClient.cpp + ${SOURCE_DIR}/rtp/RtpVideoPublisher.cpp + ${SOURCE_DIR}/webrtc/MediasoupClient.cpp ) set(LIBWEBRTC_BINARY_PATH ${LIBWEBRTC_BINARY_PATH}/${ANDROID_ABI} CACHE STRING "libwebrtc binary path" FORCE) diff --git a/taoyao-client-android/taoyao/media/src/main/AndroidManifest.xml b/taoyao-client-android/taoyao/media/src/main/AndroidManifest.xml index e4354c9..800a77f 100644 --- a/taoyao-client-android/taoyao/media/src/main/AndroidManifest.xml +++ b/taoyao-client-android/taoyao/media/src/main/AndroidManifest.xml @@ -4,6 +4,11 @@ + + + + + \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/include/AudioPublisher.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/include/LocalClient.hpp similarity index 100% rename from taoyao-client-android/taoyao/media/src/main/cpp/include/AudioPublisher.hpp rename to taoyao-client-android/taoyao/media/src/main/cpp/include/LocalClient.hpp diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/include/MediaPublisher.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/include/MediaPublisher.hpp deleted file mode 100644 index 7cfff5c..0000000 --- a/taoyao-client-android/taoyao/media/src/main/cpp/include/MediaPublisher.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -// 通道类型:rtp -#define TRANSPORT_RTP "RTP" -// 通道类型:webrtc -#define TRANSPORT_WEBRTC "WEBRTC" - -namespace acgist { - -} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/include/MediaRecorder.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/include/MediaRecorder.hpp index 4a088fe..f7883f8 100644 --- a/taoyao-client-android/taoyao/media/src/main/cpp/include/MediaRecorder.hpp +++ b/taoyao-client-android/taoyao/media/src/main/cpp/include/MediaRecorder.hpp @@ -1,5 +1,5 @@ #pragma once namespace acgist { - + } \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/include/VideoPublisher.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/include/MediasoupClient.hpp similarity index 87% rename from taoyao-client-android/taoyao/media/src/main/cpp/include/VideoPublisher.hpp rename to taoyao-client-android/taoyao/media/src/main/cpp/include/MediasoupClient.hpp index 4a088fe..f7883f8 100644 --- a/taoyao-client-android/taoyao/media/src/main/cpp/include/VideoPublisher.hpp +++ b/taoyao-client-android/taoyao/media/src/main/cpp/include/MediasoupClient.hpp @@ -1,5 +1,5 @@ #pragma once namespace acgist { - + } \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/include/P2PClient.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/include/P2PClient.hpp new file mode 100644 index 0000000..f7883f8 --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/include/P2PClient.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/include/RemoteClient.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/include/RemoteClient.hpp new file mode 100644 index 0000000..f7883f8 --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/include/RemoteClient.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/include/Room.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/include/Room.hpp new file mode 100644 index 0000000..f7883f8 --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/include/Room.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpAudioPublisher.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpAudioPublisher.hpp new file mode 100644 index 0000000..f7883f8 --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpAudioPublisher.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpClient.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpClient.hpp new file mode 100644 index 0000000..f7883f8 --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpClient.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpVideoPublisher.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpVideoPublisher.hpp new file mode 100644 index 0000000..f7883f8 --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/include/RtpVideoPublisher.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/media/LocalClient.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/media/LocalClient.cpp new file mode 100644 index 0000000..82b4b50 --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/media/LocalClient.cpp @@ -0,0 +1,7 @@ +#include + +#include "LocalClient.hpp" + +namespace acgist { + +} diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/media/MediaRecorder.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/media/MediaRecorder.cpp new file mode 100644 index 0000000..aaaa246 --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/media/MediaRecorder.cpp @@ -0,0 +1,5 @@ +#include "MediaRecorder.hpp" + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/media/P2PClient.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/media/P2PClient.cpp new file mode 100644 index 0000000..7a80561 --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/media/P2PClient.cpp @@ -0,0 +1,5 @@ +#include "P2PClient.hpp" + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/media/RemoteClient.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/media/RemoteClient.cpp new file mode 100644 index 0000000..6974b88 --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/media/RemoteClient.cpp @@ -0,0 +1,5 @@ +#include "RemoteClient.hpp" + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/media/Room.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/media/Room.cpp new file mode 100644 index 0000000..73f9bfb --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/media/Room.cpp @@ -0,0 +1,5 @@ +#include "Room.hpp" + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/rtp.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/rtp.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/rtp.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/rtp.hpp deleted file mode 100644 index 7b9637e..0000000 --- a/taoyao-client-android/taoyao/media/src/main/cpp/rtp.hpp +++ /dev/null @@ -1 +0,0 @@ -#pragma once \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpAudioPublisher.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpAudioPublisher.cpp new file mode 100644 index 0000000..92abd1e --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpAudioPublisher.cpp @@ -0,0 +1,5 @@ +#include "RtpAudioPublisher.hpp" + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpClient.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpClient.cpp new file mode 100644 index 0000000..9870cfa --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpClient.cpp @@ -0,0 +1,5 @@ +#include "RtpClient.hpp" + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpVideoPublisher.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpVideoPublisher.cpp new file mode 100644 index 0000000..6717f7a --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/rtp/RtpVideoPublisher.cpp @@ -0,0 +1,5 @@ +#include "RtpVideoPublisher.hpp" + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/webrtc.cpp deleted file mode 100644 index 775edf1..0000000 --- a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc.cpp +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc.hpp b/taoyao-client-android/taoyao/media/src/main/cpp/webrtc.hpp deleted file mode 100644 index 6f70f09..0000000 --- a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc.hpp +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/AudioPublisher.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/AudioPublisher.cpp deleted file mode 100644 index 39fd603..0000000 --- a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/AudioPublisher.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "../include/AudioPublisher.hpp" - -namespace acgist { - -} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/MediaPublisher.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/MediaPublisher.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/MediaRecorder.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/MediaRecorder.cpp deleted file mode 100644 index 75e8d63..0000000 --- a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/MediaRecorder.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "../include/MediaRecorder.hpp" - -namespace acgist { - -} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/MediasoupClient.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/MediasoupClient.cpp new file mode 100644 index 0000000..b428262 --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/MediasoupClient.cpp @@ -0,0 +1,5 @@ +#include "MediasoupClient.hpp" + +namespace acgist { + +} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/VideoPublisher.cpp b/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/VideoPublisher.cpp deleted file mode 100644 index fc40e38..0000000 --- a/taoyao-client-android/taoyao/media/src/main/cpp/webrtc/VideoPublisher.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "../include/VideoPublisher.hpp" - -namespace acgist { - -} \ No newline at end of file diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/RoomClient.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/LocalClient.java similarity index 82% rename from taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/RoomClient.java rename to taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/LocalClient.java index 1d2ba9f..afafe57 100644 --- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/RoomClient.java +++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/LocalClient.java @@ -6,8 +6,7 @@ package com.acgist.taoyao.media; * * @author acgist */ -public class RoomClient { - +public class LocalClient { } 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 new file mode 100644 index 0000000..ce3ed18 --- /dev/null +++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/MediaManager.java @@ -0,0 +1,310 @@ +package com.acgist.taoyao.media; + +import android.content.Context; +import android.util.Log; + +import org.webrtc.AudioSource; +import org.webrtc.AudioTrack; +import org.webrtc.Camera2Enumerator; +import org.webrtc.CameraEnumerator; +import org.webrtc.CameraVideoCapturer; +import org.webrtc.EglBase; +import org.webrtc.MediaConstraints; +import org.webrtc.MediaStream; +import org.webrtc.PeerConnectionFactory; +import org.webrtc.SurfaceTextureHelper; +import org.webrtc.SurfaceViewRenderer; +import org.webrtc.VideoCapturer; +import org.webrtc.VideoSource; +import org.webrtc.VideoTrack; +import org.webrtc.voiceengine.WebRtcAudioUtils; + +import java.util.Iterator; +import java.util.List; + +/** + * 媒体来源管理器 + * + * @author acgist + */ +public class MediaManager { + + /** + * 来源类型 + * + * @author acgist + */ + public enum Type { + + // 后置摄像头 + BACK, + // 前置摄像头 + FRONT, + // 屏幕共享 + SCREEN; + + } + + /** + * 视频类型 + */ + private Type type; + /** + * 上下文 + */ + private Context context; + /** + * 媒体流:声音、主码流(预览流)、次码流 + */ + private MediaStream mediaStream; + /** + * 屏幕捕获 + */ + private VideoCapturer videoCapturer; + /** + * 摄像头捕获 + */ + private CameraVideoCapturer cameraVideoCapturer; + /** + * Peer连接工厂 + */ + private PeerConnectionFactory peerConnectionFactory; + /** + * 预览 + */ + private SurfaceViewRenderer previewView; + + static { + // 设置采样 +// WebRtcAudioUtils.setDefaultSampleRateHz(); + // 噪声消除 + WebRtcAudioUtils.setWebRtcBasedNoiseSuppressor(true); + // 回声小丑 + WebRtcAudioUtils.setWebRtcBasedAcousticEchoCanceler(true); + } + + /** + * 加载媒体流 + */ + public void init() { + this.peerConnectionFactory = PeerConnectionFactory.builder().createPeerConnectionFactory(); + this.mediaStream = this.peerConnectionFactory.createLocalMediaStream("ARDAMS"); + } + + /** + * 切换视频来源 + * + * @param type 来源类型 + * + * TODO:设置分享 + */ + public void exchange(Type type) { + if(this.type == type) { + return; + } + this.type = type; + Log.i(MediaManager.class.getSimpleName(), "设置视频来源:" + type); + if(this.type == Type.SCREEN || type == Type.SCREEN) { + this.initVideo(); + } else { + // TODO:测试是否需要完全重置 + this.cameraVideoCapturer.switchCamera(new CameraVideoCapturer.CameraSwitchHandler() { + @Override + public void onCameraSwitchDone(boolean success) { + } + @Override + public void onCameraSwitchError(String message) { + } + }); + } + } + + /** + * 加载音频 + */ + private void initAudio() { + // 关闭音频 + this.closeAudioTrack(); + // 加载音频 + final MediaConstraints mediaConstraints = new MediaConstraints(); + final AudioSource audioSource = this.peerConnectionFactory.createAudioSource(mediaConstraints); + final AudioTrack audioTrack = this.peerConnectionFactory.createAudioTrack("ARDAMSa0", audioSource); + audioTrack.setEnabled(true); + this.mediaStream.addTrack(audioTrack); + Log.i(MediaManager.class.getSimpleName(), "加载音频:" + audioTrack.id()); + } + + /** + * 加载视频 + */ + private void initVideo() { + this.closeVideoTrack(); + if(this.cameraVideoCapturer != null) { + this.cameraVideoCapturer.dispose(); + } + final CameraEnumerator cameraEnumerator = new Camera2Enumerator(this.context); + final String[] names = cameraEnumerator.getDeviceNames(); + for(String name : names) { + if(this.type == Type.FRONT && cameraEnumerator.isFrontFacing(name)) { + Log.i(MediaManager.class.getSimpleName(), "加载前置摄像头:" + name); + this.cameraVideoCapturer = cameraEnumerator.createCapturer(name, new MediaCameraEventsHandler()); + } else if(this.type == Type.BACK && cameraEnumerator.isBackFacing(name)) { + Log.i(MediaManager.class.getSimpleName(), "加载后置摄像头:" + name); + this.cameraVideoCapturer = cameraEnumerator.createCapturer(name, new MediaCameraEventsHandler()); + } else { + Log.i(MediaManager.class.getSimpleName(), "忽略摄像头:" + name); + } + } + } + + /** + * 加载视频 + */ + private void initVideoTrack() { + SurfaceTextureHelper surfaceTextureHelper = null; + // 设置预览 + if(this.previewView != null) { + final EglBase eglBase = EglBase.create(); + surfaceTextureHelper = SurfaceTextureHelper.create("MediaVideoThread", eglBase.getEglBaseContext()); + this.previewView.setMirror(true); + this.previewView.setEnableHardwareScaler(true); + } + // 是否捕获屏幕 + final boolean screen = this.type == Type.SCREEN; + final VideoSource videoSource = this.peerConnectionFactory.createVideoSource(screen); + 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); + videoTrack.setEnabled(true); + this.mediaStream.addTrack(videoTrack); + Log.i(MediaManager.class.getSimpleName(), "加载视频:" + videoTrack.id()); + } + + private void initPreview() { + } + + public void pauseAudio() { + synchronized (this.mediaStream.audioTracks) { + this.mediaStream.audioTracks.forEach(a -> a.setEnabled(false)); + } + } + + public void resumeAudio() { + synchronized (this.mediaStream.audioTracks) { + this.mediaStream.audioTracks.forEach(a -> a.setEnabled(true)); + } + } + + public void pauseVideo() { + synchronized (this.mediaStream.videoTracks) { + this.mediaStream.videoTracks.forEach(v -> v.setEnabled(false)); + } + synchronized (this.mediaStream.preservedVideoTracks) { + this.mediaStream.preservedVideoTracks.forEach(v -> v.setEnabled(false)); + } + } + + public void resumeVideo() { + synchronized (this.mediaStream.videoTracks) { + this.mediaStream.videoTracks.forEach(v -> v.setEnabled(true)); + } + synchronized (this.mediaStream.preservedVideoTracks) { + this.mediaStream.preservedVideoTracks.forEach(v -> v.setEnabled(true)); + } + } + + /** + * 关闭声音 + */ + private void closeAudioTrack() { + synchronized (this.mediaStream.audioTracks) { + AudioTrack track; + final Iterator iterator = this.mediaStream.audioTracks.iterator(); + while(iterator.hasNext()) { + track = iterator.next(); + iterator.remove(); + track.dispose(); + } + } + } + + /** + * 关闭视频 + */ + private void closeVideoTrack() { + // 次码流 + this.closeVideoTrack(this.mediaStream.videoTracks); + // 主码流 + this.closeVideoTrack(this.mediaStream.preservedVideoTracks); + } + + /** + * 关闭视频 + * + * @param list 视频列表 + */ + private void closeVideoTrack(List list) { + synchronized (list) { + VideoTrack track; + final Iterator iterator = list.iterator(); + while(iterator.hasNext()) { + track = iterator.next(); + iterator.remove(); + track.dispose(); + } + } + } + + /** + * 释放资源 + */ + public void close() { + if(this.cameraVideoCapturer != null) { + this.cameraVideoCapturer.dispose(); + } + if(this.mediaStream != null) { + this.mediaStream.dispose(); + } + if(this.peerConnectionFactory != null) { + this.peerConnectionFactory.dispose(); + } + } + + /** + * 摄像头事件 + * + * @author acgist + */ + private static class MediaCameraEventsHandler implements CameraVideoCapturer.CameraEventsHandler { + + @Override + public void onCameraError(String message) { + } + + @Override + public void onCameraDisconnected() { + } + + @Override + public void onCameraFreezed(String message) { + } + + @Override + public void onCameraOpening(String message) { + } + + @Override + public void onFirstFrameAvailable() { + } + + @Override + public void onCameraClosed() { + } + } + +} diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/ClientRecorder.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/MediaRecorder.java similarity index 64% rename from taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/ClientRecorder.java rename to taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/MediaRecorder.java index e95ba8d..2f5cb9c 100644 --- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/ClientRecorder.java +++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/MediaRecorder.java @@ -5,16 +5,16 @@ package com.acgist.taoyao.media; * * @author acgist */ -public final class ClientRecorder { +public final class MediaRecorder { /** * 是否正在录像 */ private boolean active; - private static final ClientRecorder INSTANCE = new ClientRecorder(); + private static final MediaRecorder INSTANCE = new MediaRecorder(); - public static final ClientRecorder getInstance() { + public static final MediaRecorder getInstance() { return INSTANCE; } diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/p2p/P2PClient.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/P2PClient.java similarity index 77% rename from taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/p2p/P2PClient.java rename to taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/P2PClient.java index d26d5b6..9027cb4 100644 --- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/p2p/P2PClient.java +++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/P2PClient.java @@ -1,4 +1,4 @@ -package com.acgist.taoyao.p2p; +package com.acgist.taoyao.media; /** * P2P终端 diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/AudioPublisher.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/RemoteClient.java similarity index 54% rename from taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/AudioPublisher.java rename to taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/RemoteClient.java index 66455bd..37161c3 100644 --- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/AudioPublisher.java +++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/RemoteClient.java @@ -1,4 +1,4 @@ package com.acgist.taoyao.media; -public class AudioPublisher { +public class RemoteClient { } diff --git a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/VideoPublisher.java b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/Room.java similarity index 54% rename from taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/VideoPublisher.java rename to taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/Room.java index 47a6735..bbf8ab4 100644 --- a/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/VideoPublisher.java +++ b/taoyao-client-android/taoyao/media/src/main/java/com/acgist/taoyao/media/Room.java @@ -1,4 +1,4 @@ package com.acgist.taoyao.media; -public class VideoPublisher { +public class Room { }