[*] 写了一点
This commit is contained in:
@@ -1,11 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
@@ -18,6 +13,7 @@
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/title_activity_main"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/Theme.Taoyao">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
@@ -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(), "拉起媒体服务失败");
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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()
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -12,4 +12,7 @@
|
||||
<string name="encrypt">DES</string>
|
||||
<!-- 信令加密密钥 -->
|
||||
<string name="encryptSecret">2SPWy+TF1zM=</string>
|
||||
<!-- 文件存储目录 -->
|
||||
<string name="storagePathImage">/taoyao/image</string>
|
||||
<string name="storagePathVideo">/taoyao/video</string>
|
||||
</resources>
|
||||
@@ -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)
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
</manifest>
|
||||
@@ -1,10 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// 通道类型:rtp
|
||||
#define TRANSPORT_RTP "RTP"
|
||||
// 通道类型:webrtc
|
||||
#define TRANSPORT_WEBRTC "WEBRTC"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
namespace acgist {
|
||||
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
namespace acgist {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include "LocalClient.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "MediaRecorder.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "P2PClient.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "RemoteClient.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "Room.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
#pragma once
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "RtpAudioPublisher.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "RtpClient.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "RtpVideoPublisher.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
#include <jni.h>
|
||||
@@ -1 +0,0 @@
|
||||
#pragma once
|
||||
@@ -1,5 +0,0 @@
|
||||
#include "../include/AudioPublisher.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
#include "../include/MediaRecorder.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "MediasoupClient.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
#include "../include/VideoPublisher.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
}
|
||||
@@ -6,8 +6,7 @@ package com.acgist.taoyao.media;
|
||||
*
|
||||
* @author acgist
|
||||
*/
|
||||
public class RoomClient {
|
||||
|
||||
public class LocalClient {
|
||||
|
||||
|
||||
}
|
||||
@@ -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<AudioTrack> 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<VideoTrack> list) {
|
||||
synchronized (list) {
|
||||
VideoTrack track;
|
||||
final Iterator<VideoTrack> 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() {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.acgist.taoyao.p2p;
|
||||
package com.acgist.taoyao.media;
|
||||
|
||||
/**
|
||||
* P2P终端
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.acgist.taoyao.media;
|
||||
|
||||
public class AudioPublisher {
|
||||
public class RemoteClient {
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.acgist.taoyao.media;
|
||||
|
||||
public class VideoPublisher {
|
||||
public class Room {
|
||||
}
|
||||
Reference in New Issue
Block a user