[*] 回调
This commit is contained in:
@@ -25,9 +25,9 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
||||
implementation 'org.apache.commons:commons-collections4:4.4'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
|
||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2'
|
||||
api 'org.apache.commons:commons-lang3:3.12.0'
|
||||
api 'org.apache.commons:commons-collections4:4.4'
|
||||
api 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
|
||||
api 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
}
|
||||
|
||||
@@ -156,16 +156,8 @@ public class Message implements Cloneable, Serializable {
|
||||
/**
|
||||
* @return Map消息主体
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public Map<String, Object> body() {
|
||||
if (this.body instanceof Map) {
|
||||
return (Map<String, Object>) this.body;
|
||||
} else if (this.body == null) {
|
||||
return new HashMap<>();
|
||||
} else {
|
||||
Log.w(Message.class.getSimpleName(), "信令主体类型错误:" + this.body);
|
||||
return new HashMap<>();
|
||||
}
|
||||
public <T> T body() {
|
||||
return (T) this.body;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,11 +32,7 @@ dependencies {
|
||||
implementation project(path: ':boot')
|
||||
implementation project(path: ':media')
|
||||
implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||
implementation 'com.google.android.material:material:1.8.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
||||
implementation 'org.apache.commons:commons-collections4:4.4'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
|
||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2'
|
||||
implementation 'com.google.android.material:material:1.8.0'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
}
|
||||
|
||||
@@ -147,7 +147,6 @@ public class MainActivity extends AppCompatActivity implements Serializable {
|
||||
final Resources resources = this.getResources();
|
||||
MediaManager.getInstance().initContext(
|
||||
this.mainHandler, this.getApplicationContext(),
|
||||
resources.getBoolean(R.bool.preview),
|
||||
resources.getBoolean(R.bool.playAudio),
|
||||
resources.getBoolean(R.bool.playVideo),
|
||||
resources.getBoolean(R.bool.audioConsume),
|
||||
@@ -210,7 +209,7 @@ public class MainActivity extends AppCompatActivity implements Serializable {
|
||||
private void action(View view) {
|
||||
this.threadHandler.post(() -> {
|
||||
// 进入房间
|
||||
Taoyao.taoyao.roomEnter("d8f1e91c-58d0-4e58-ad67-decc0fd61df2", null);
|
||||
Taoyao.taoyao.roomEnter("022a16bd-94b9-4d40-889e-d364da065bd2", null);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,12 @@ import android.widget.Toast;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import com.acgist.taoyao.boot.model.Message;
|
||||
import com.acgist.taoyao.client.signal.Taoyao;
|
||||
import com.acgist.taoyao.media.MediaManager;
|
||||
import com.acgist.taoyao.media.signal.ITaoyaoListener;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 媒体服务
|
||||
@@ -53,6 +57,8 @@ public class MediaService extends Service {
|
||||
|
||||
private Taoyao taoyao;
|
||||
private Handler mainHandler;
|
||||
private final ITaoyaoListener taoyaoListener = new ITaoyaoListener() {
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
@@ -154,7 +160,7 @@ public class MediaService extends Service {
|
||||
port, host, resources.getString(R.string.version),
|
||||
name, clientId, resources.getString(R.string.clientType), username, password,
|
||||
resources.getInteger(R.integer.timeout), resources.getString(R.string.encrypt), resources.getString(R.string.encryptSecret),
|
||||
this.mainHandler, context
|
||||
this.mainHandler, context, this.taoyaoListener
|
||||
);
|
||||
MediaManager.getInstance().initTaoyao(this.taoyao);
|
||||
Toast.makeText(this.getApplicationContext(), "连接信令", Toast.LENGTH_SHORT).show();
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.acgist.taoyao.media.MediaManager;
|
||||
import com.acgist.taoyao.media.client.Room;
|
||||
import com.acgist.taoyao.media.client.SessionClient;
|
||||
import com.acgist.taoyao.media.signal.ITaoyao;
|
||||
import com.acgist.taoyao.media.signal.ITaoyaoListener;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@@ -130,6 +131,10 @@ public final class Taoyao implements ITaoyao {
|
||||
* 服务上下文
|
||||
*/
|
||||
private final Context context;
|
||||
/**
|
||||
* 信令监听
|
||||
*/
|
||||
private final ITaoyaoListener taoyaoListener;
|
||||
/**
|
||||
* Wifi管理器
|
||||
*/
|
||||
@@ -175,7 +180,7 @@ public final class Taoyao implements ITaoyao {
|
||||
int port, String host, String version,
|
||||
String name, String clientId, String clientType, String username, String password,
|
||||
int timeout, String algo, String secret,
|
||||
Handler mainHandler, Context context
|
||||
Handler mainHandler, Context context, ITaoyaoListener taoyaoListener
|
||||
) {
|
||||
this.close = false;
|
||||
this.connect = false;
|
||||
@@ -193,6 +198,7 @@ public final class Taoyao implements ITaoyao {
|
||||
this.decrypt = plaintext ? null : this.buildCipher(Cipher.DECRYPT_MODE, algo, secret);
|
||||
this.mainHandler = mainHandler;
|
||||
this.context = context;
|
||||
this.taoyaoListener = taoyaoListener;
|
||||
this.wifiManager = context.getSystemService(WifiManager.class);
|
||||
this.powerManager = context.getSystemService(PowerManager.class);
|
||||
this.batteryManager = context.getSystemService(BatteryManager.class);
|
||||
@@ -246,6 +252,7 @@ public final class Taoyao implements ITaoyao {
|
||||
// 开始连接
|
||||
Log.d(Taoyao.class.getSimpleName(), "连接信令:" + this.host + ":" + this.port);
|
||||
this.socket = new Socket();
|
||||
this.taoyaoListener.onConnect();
|
||||
try {
|
||||
// 设置读取超时时间:不要设置一直阻塞
|
||||
// socket.setSoTimeout(this.timeout);
|
||||
@@ -255,6 +262,7 @@ public final class Taoyao implements ITaoyao {
|
||||
this.output = this.socket.getOutputStream();
|
||||
this.clientRegister();
|
||||
this.connect = true;
|
||||
this.taoyaoListener.onConnected();
|
||||
synchronized (this) {
|
||||
this.notifyAll();
|
||||
}
|
||||
@@ -320,6 +328,7 @@ public final class Taoyao implements ITaoyao {
|
||||
Taoyao.this.on(content);
|
||||
} catch (Exception e) {
|
||||
Log.e(Taoyao.class.getSimpleName(), "处理信令异常:" + content, e);
|
||||
this.taoyaoListener.onError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -407,6 +416,7 @@ public final class Taoyao implements ITaoyao {
|
||||
if(!this.connect) {
|
||||
return;
|
||||
}
|
||||
this.taoyaoListener.onDisconnect();
|
||||
Log.d(Taoyao.class.getSimpleName(), "释放信令:" + this.host + ":" + this.port);
|
||||
this.connect = false;
|
||||
CloseableUtils.close(this.input);
|
||||
@@ -497,36 +507,39 @@ public final class Taoyao implements ITaoyao {
|
||||
}
|
||||
|
||||
private void dispatch(final String content, final Header header, final Message message) {
|
||||
final Map<String, Object> body = message.body();
|
||||
if(this.taoyaoListener.preOnMessage(message)) {
|
||||
return;
|
||||
}
|
||||
switch (header.getSignal()) {
|
||||
case "client::config" -> this.clientConfig(message, body);
|
||||
case "client::register" -> this.clientRegister(message, body);
|
||||
case "client::reboot" -> this.clientReboot(message, body);
|
||||
case "client::shutdown" -> this.clientShutdown(message, body);
|
||||
case "media::consume" -> this.mediaConsume(message, body);
|
||||
// case "media::audio::volume" -> this.mediaAudioVolume(message, body);
|
||||
case "media::consumer::close" -> this.mediaConsumerClose(message, body);
|
||||
case "media::consumer::pause" -> this.mediaConsumerPause(message, body);
|
||||
// case "media::consumer::request::key::frame" -> this.mediaConsumerRequestKeyFrame(message, body);
|
||||
case "media::consumer::resume" -> this.mediaConsumerResume(message, body);
|
||||
// case "media::consumer::set::preferred::layers" -> this.mediaConsumerSetPreferredLayers(message, body);
|
||||
// case "media::consumer::status" -> this.mediaConsumerStatus(message, body);
|
||||
case "media::producer::close" -> this.mediaProducerClose(message, body);
|
||||
case "media::producer::pause" -> this.mediaProducerPause(message, body);
|
||||
case "media::producer::resume" -> this.mediaProducerResume(message, body);
|
||||
// case "media::producer::video::orientation:change" -> this.mediaVideoOrientationChange(message, body);
|
||||
case "room::close" -> this.roomClose(message, body);
|
||||
case "room::enter" -> this.roomEnter(message, body);
|
||||
case "room::expel" -> this.roomExpel(message, body);
|
||||
case "room::invite" -> this.roomInivte(message, body);
|
||||
case "room::leave" -> this.roomLeave(message, body);
|
||||
case "session::call" -> this.sessionCall(message, body);
|
||||
case "session::close" -> this.sessionClose(message, body);
|
||||
case "session::exchange" -> this.sessionExchange(message, body);
|
||||
case "session::pause" -> this.sessionPause(message, body);
|
||||
case "session::resume" -> this.sessionResume(message, body);
|
||||
case "client::config" -> this.clientConfig(message, message.body());
|
||||
case "client::register" -> this.clientRegister(message, message.body());
|
||||
case "client::reboot" -> this.clientReboot(message, message.body());
|
||||
case "client::shutdown" -> this.clientShutdown(message, message.body());
|
||||
case "media::consume" -> this.mediaConsume(message, message.body());
|
||||
// case "media::audio::volume" -> this.mediaAudioVolume(message, message.body());
|
||||
case "media::consumer::close" -> this.mediaConsumerClose(message, message.body());
|
||||
case "media::consumer::pause" -> this.mediaConsumerPause(message, message.body());
|
||||
// case "media::consumer::request::key::frame" -> this.mediaConsumerRequestKeyFrame(message, message.body());
|
||||
case "media::consumer::resume" -> this.mediaConsumerResume(message, message.body());
|
||||
// case "media::consumer::set::preferred::layers" -> this.mediaConsumerSetPreferredLayers(message, message.body());
|
||||
// case "media::consumer::status" -> this.mediaConsumerStatus(message, message.body());
|
||||
case "media::producer::close" -> this.mediaProducerClose(message, message.body());
|
||||
case "media::producer::pause" -> this.mediaProducerPause(message, message.body());
|
||||
case "media::producer::resume" -> this.mediaProducerResume(message, message.body());
|
||||
// case "media::producer::video::orientation:change" -> this.mediaVideoOrientationChange(message, message.body());
|
||||
case "room::close" -> this.roomClose(message, message.body());
|
||||
case "room::enter" -> this.roomEnter(message, message.body());
|
||||
case "room::expel" -> this.roomExpel(message, message.body());
|
||||
case "room::invite" -> this.roomInivte(message, message.body());
|
||||
case "room::leave" -> this.roomLeave(message, message.body());
|
||||
case "session::call" -> this.sessionCall(message, message.body());
|
||||
case "session::close" -> this.sessionClose(message, message.body());
|
||||
case "session::exchange" -> this.sessionExchange(message, message.body());
|
||||
case "session::pause" -> this.sessionPause(message, message.body());
|
||||
case "session::resume" -> this.sessionResume(message, message.body());
|
||||
default -> Log.d(Taoyao.class.getSimpleName(), "没有适配信令:" + content);
|
||||
}
|
||||
this.taoyaoListener.postOnMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -672,6 +685,7 @@ public final class Taoyao implements ITaoyao {
|
||||
this.name, this.clientId,
|
||||
key, password,
|
||||
this, this.mainHandler,
|
||||
resources.getBoolean(R.bool.preview),
|
||||
resources.getBoolean(R.bool.dataConsume),
|
||||
resources.getBoolean(R.bool.audioConsume),
|
||||
resources.getBoolean(R.bool.videoConsume),
|
||||
|
||||
@@ -28,6 +28,7 @@ set(
|
||||
${SOURCE_DIR}/include/Log.hpp
|
||||
${SOURCE_DIR}/include/MediaManager.hpp
|
||||
${SOURCE_DIR}/include/Room.hpp
|
||||
${SOURCE_DIR}/include/RouterCallback.hpp
|
||||
${SOURCE_DIR}/include/RtpAudioPublisher.hpp
|
||||
${SOURCE_DIR}/include/RtpClient.hpp
|
||||
${SOURCE_DIR}/include/RtpVideoPublisher.hpp
|
||||
@@ -36,6 +37,7 @@ set(
|
||||
${SOURCE_DIR}/rtp/RtpVideoPublisher.cpp
|
||||
${SOURCE_DIR}/webrtc/MediaManager.cpp
|
||||
${SOURCE_DIR}/webrtc/Room.cpp
|
||||
${SOURCE_DIR}/webrtc/RouterCallback.cpp
|
||||
)
|
||||
|
||||
set(LIBWEBRTC_BINARY_PATH ${LIBWEBRTC_BINARY_PATH}/${ANDROID_ABI} CACHE STRING "libwebrtc binary path" FORCE)
|
||||
|
||||
@@ -53,11 +53,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(path: ':boot')
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
||||
implementation 'org.apache.commons:commons-collections4:4.4'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
|
||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2'
|
||||
api project(path: ':boot')
|
||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
}
|
||||
|
||||
@@ -6,8 +6,14 @@ namespace acgist {
|
||||
|
||||
#define LOG_TAG "libtaoyao"
|
||||
|
||||
#define LOG_D(message, ...) acgist::__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, message, __VA_ARGS__)
|
||||
#define LOG_I(message, ...) acgist::__android_log_print(ANDROID_LOG_INFO, LOG_TAG, message, __VA_ARGS__)
|
||||
#define LOG_W(message, ...) acgist::__android_log_print(ANDROID_LOG_WARN, LOG_TAG, message, __VA_ARGS__)
|
||||
#define LOG_E(message, ...) acgist::__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, message, __VA_ARGS__)
|
||||
#define LOG_D(format, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "%s " format, __func__, ##__VA_ARGS__)
|
||||
#define LOG_I(format, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "%s " format, __func__, ##__VA_ARGS__)
|
||||
#define LOG_W(format, ...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "%s " format, __func__, ##__VA_ARGS__)
|
||||
#define LOG_E(format, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "%s " format, __func__, ##__VA_ARGS__)
|
||||
|
||||
//#define LOG_D(...) acgist::__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
||||
//#define LOG_I(...) acgist::__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
||||
//#define LOG_W(...) acgist::__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
|
||||
//#define LOG_E(...) acgist::__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
#include "jni.h"
|
||||
#include "Log.hpp"
|
||||
#include "mediasoupclient.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
jmethodID closeCallback;
|
||||
|
||||
}
|
||||
@@ -1,44 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "jni.h"
|
||||
#include "sdk/android/src/jni/pc/peer_connection.h"
|
||||
#include "sdk/android/native_api/jni/scoped_java_ref.h"
|
||||
|
||||
#include "Log.hpp"
|
||||
#include "mediasoupclient.hpp"
|
||||
#include "RouterCallback.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
class Room {
|
||||
class Room : public RouterCallback {
|
||||
public:
|
||||
std::string roomId;
|
||||
mediasoupclient::Device *device;
|
||||
mediasoupclient::PeerConnection *peerConnection;
|
||||
mediasoupclient::SendTransport *sendTransport;
|
||||
mediasoupclient::RecvTransport *recvTransport;
|
||||
mediasoupclient::SendTransport::Listener *sendListener;
|
||||
mediasoupclient::RecvTransport::Listener *recvListener;
|
||||
mediasoupclient::Producer *audioProducer;
|
||||
mediasoupclient::Producer *videoProducer;
|
||||
mediasoupclient::Producer::Listener *producerListener;
|
||||
mediasoupclient::Consumer::Listener *consumerListener;
|
||||
mediasoupclient::Device* device;
|
||||
mediasoupclient::PeerConnection* peerConnection;
|
||||
mediasoupclient::SendTransport* sendTransport;
|
||||
mediasoupclient::RecvTransport* recvTransport;
|
||||
mediasoupclient::SendTransport::Listener* sendListener;
|
||||
mediasoupclient::RecvTransport::Listener* recvListener;
|
||||
mediasoupclient::Producer* audioProducer;
|
||||
mediasoupclient::Producer* videoProducer;
|
||||
mediasoupclient::Producer::Listener* producerListener;
|
||||
mediasoupclient::Consumer::Listener* consumerListener;
|
||||
std::map<std::string, mediasoupclient::Consumer*> consumers;
|
||||
public:
|
||||
JNIEnv *env;
|
||||
jobject routerCallback;
|
||||
public:
|
||||
Room(std::string roomId, JNIEnv *env, jobject routerCallback);
|
||||
Room(std::string roomId, JNIEnv* env, jobject routerCallback);
|
||||
virtual ~Room();
|
||||
public:
|
||||
void enter(std::string rtpCapabilities, webrtc::PeerConnectionFactoryInterface *factory, webrtc::PeerConnectionInterface::RTCConfiguration &rtcConfiguration);
|
||||
void enter(std::string rtpCapabilities, webrtc::PeerConnectionFactoryInterface* factory, webrtc::PeerConnectionInterface::RTCConfiguration& rtcConfiguration);
|
||||
void createSendTransport(std::string body);
|
||||
void createRecvTransport(std::string body);
|
||||
void mediaProduceAudio(webrtc::MediaStreamInterface *mediaStream);
|
||||
void mediaProduceVideo(webrtc::MediaStreamInterface *mediaStream);
|
||||
void mediaProduceAudio(webrtc::MediaStreamInterface* mediaStream);
|
||||
void mediaProduceVideo(webrtc::MediaStreamInterface* mediaStream);
|
||||
void mediaConsume(std::string message);
|
||||
void mediaProducerPause(std::string producerId);
|
||||
void mediaProducerResume(std::string producerId);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "jni.h"
|
||||
#include "mediasoupclient.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
class RouterCallback {
|
||||
public:
|
||||
JNIEnv* env;
|
||||
jobject routerCallback;
|
||||
public:
|
||||
void enterCallback(std::string rtpCapabilities, std::string sctpCapabilities);
|
||||
void sendTransportConnectCallback(std::string transportId, std::string dtlsParameters);
|
||||
std::string sendTransportProduceCallback(std::string kind, std::string transportId, std::string rtpParameters);
|
||||
void recvTransportConnectCallback(std::string transportId, std::string dtlsParameters);
|
||||
void producerNewCallback(std::string kind, std::string producerId, webrtc::MediaStreamTrackInterface* producerMediaTrackPointer);
|
||||
void producerPauseCallback(std::string producerId);
|
||||
void producerResumeCallback(std::string producerId);
|
||||
void producerCloseCallback(std::string producerId);
|
||||
void consumerNewCallback(std::string message, webrtc::MediaStreamTrackInterface* consumerMediaTrackPointer);
|
||||
void consumerPauseCallback(std::string consumerId);
|
||||
void consumerResumeCallback(std::string consumerId);
|
||||
void consumerCloseCallback(std::string consumerId);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "Room.hpp"
|
||||
#include "MediaManager.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_MediaManager_nativeInit(JNIEnv *env, jobject me) {
|
||||
LOG_I("加载MediasoupClient:", mediasoupclient::Version().data());
|
||||
Java_com_acgist_taoyao_media_MediaManager_nativeInit(JNIEnv* env, jobject me) {
|
||||
std::string version = mediasoupclient::Version();
|
||||
LOG_I("加载MediasoupClient", version.data());
|
||||
mediasoupclient::Initialize();
|
||||
// => { spatialLayers: 2, temporalLayers: 3 }
|
||||
// mediasoupclient::parseScalabilityMode("L2T3");
|
||||
@@ -14,8 +14,8 @@ namespace acgist {
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_MediaManager_nativeStop(JNIEnv *env, jobject me) {
|
||||
std::cout << "释放mediasoupclient" << std::endl;
|
||||
Java_com_acgist_taoyao_media_MediaManager_nativeStop(JNIEnv* env, jobject me) {
|
||||
LOG_I("释放mediasoupclient");
|
||||
mediasoupclient::Cleanup();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,77 +5,38 @@ namespace acgist {
|
||||
class SendListener : public mediasoupclient::SendTransport::Listener {
|
||||
|
||||
public:
|
||||
Room *room;
|
||||
JNIEnv *env;
|
||||
jobject routerCallback;
|
||||
Room* room;
|
||||
|
||||
public:
|
||||
SendListener(Room *room, JNIEnv *env, jobject routerCallback) {
|
||||
SendListener(Room* room) {
|
||||
this->room = room;
|
||||
this->env = env;
|
||||
this->routerCallback = routerCallback;
|
||||
}
|
||||
|
||||
virtual ~SendListener() {
|
||||
}
|
||||
|
||||
public:
|
||||
std::future<void> OnConnect(mediasoupclient::Transport *transport, const nlohmann::json &dtlsParameters) override {
|
||||
jclass jCallbackClazz = this->env->GetObjectClass(this->routerCallback);
|
||||
jmethodID sendTransportConnectCallback = this->env->GetMethodID(jCallbackClazz, "sendTransportConnectCallback", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
const char *cTransportId = transport->GetId().data();
|
||||
jstring jTransportId = this->env->NewStringUTF(cTransportId);
|
||||
const char *cDtlsParameters = dtlsParameters.dump().data();
|
||||
jstring jDtlsParameters = this->env->NewStringUTF(cDtlsParameters);
|
||||
this->env->CallVoidMethod(
|
||||
this->routerCallback,
|
||||
sendTransportConnectCallback,
|
||||
jTransportId,
|
||||
jDtlsParameters
|
||||
);
|
||||
this->env->DeleteLocalRef(jTransportId);
|
||||
this->env->ReleaseStringUTFChars(jTransportId, cTransportId);
|
||||
this->env->DeleteLocalRef(jDtlsParameters);
|
||||
this->env->ReleaseStringUTFChars(jDtlsParameters, cDtlsParameters);
|
||||
this->env->DeleteLocalRef(jCallbackClazz);
|
||||
std::future<void> OnConnect(mediasoupclient::Transport* transport, const nlohmann::json& dtlsParameters) override {
|
||||
const std::string cTransportId = transport->GetId();
|
||||
const std::string cDtlsParameters = dtlsParameters.dump();
|
||||
this->room->sendTransportConnectCallback(cTransportId, cDtlsParameters);
|
||||
return std::future<void>();
|
||||
}
|
||||
|
||||
void OnConnectionStateChange(mediasoupclient::Transport *transport, const std::string &connectionState) override {
|
||||
void OnConnectionStateChange(mediasoupclient::Transport* transport, const std::string& connectionState) override {
|
||||
// 状态变化
|
||||
}
|
||||
|
||||
std::future<std::string> OnProduce(mediasoupclient::SendTransport *transport, const std::string &kind, nlohmann::json rtpParameters, const nlohmann::json &appData) override {
|
||||
jclass jCallbackClazz = this->env->GetObjectClass(this->routerCallback);
|
||||
jmethodID sendTransportProduceCallback = this->env->GetMethodID(jCallbackClazz, "sendTransportProduceCallback", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
const char *cKind = kind.data();
|
||||
jstring jKind = this-> env->NewStringUTF(cKind);
|
||||
const char *cTransportId = transport->GetId().data();
|
||||
jstring jTransportId = this-> env->NewStringUTF(cTransportId);
|
||||
const char *cRtpParameters = rtpParameters.dump().data();
|
||||
jstring jRtpParameters = this-> env->NewStringUTF(cRtpParameters);
|
||||
std::promise<std::string> promise;
|
||||
jstring jResult = (jstring) this->env->CallObjectMethod(
|
||||
this->routerCallback,
|
||||
sendTransportProduceCallback,
|
||||
jKind,
|
||||
jTransportId,
|
||||
jRtpParameters
|
||||
);
|
||||
const char *cResult = this-> env->GetStringUTFChars(jResult, 0);
|
||||
std::string result(cResult);
|
||||
std::future<std::string> OnProduce(mediasoupclient::SendTransport* transport, const std::string& kind, nlohmann::json rtpParameters, const nlohmann::json& appData) override {
|
||||
const std::string cTransportId = transport->GetId();
|
||||
const std::string cRtpParameters = rtpParameters.dump();
|
||||
std::string result = this->room->sendTransportProduceCallback(kind, cTransportId, cRtpParameters);
|
||||
std::promise <std::string> promise;
|
||||
promise.set_value(result);
|
||||
this-> env->DeleteLocalRef(jResult);
|
||||
this-> env->DeleteLocalRef(jKind);
|
||||
this-> env->ReleaseStringUTFChars(jKind, cKind);
|
||||
this-> env->DeleteLocalRef(jResult);
|
||||
this-> env->ReleaseStringUTFChars(jResult, cResult);
|
||||
this-> env->DeleteLocalRef(jTransportId);
|
||||
this-> env->ReleaseStringUTFChars(jTransportId, cTransportId);
|
||||
this-> env->DeleteLocalRef(jRtpParameters);
|
||||
this-> env->ReleaseStringUTFChars(jRtpParameters, cRtpParameters);
|
||||
this-> env->DeleteLocalRef(jCallbackClazz);
|
||||
return promise.get_future();
|
||||
}
|
||||
|
||||
std::future<std::string> OnProduceData(mediasoupclient::SendTransport *transport, const nlohmann::json &sctpStreamParameters, const std::string &label, const std::string &protocol, const nlohmann::json &appData) override {
|
||||
std::future<std::string> OnProduceData(mediasoupclient::SendTransport* transport, const nlohmann::json& sctpStreamParameters, const std::string& label, const std::string& protocol, const nlohmann::json& appData) override {
|
||||
// 数据生产
|
||||
return std::future<std::string>();
|
||||
}
|
||||
@@ -85,39 +46,24 @@ namespace acgist {
|
||||
class RecvListener : public mediasoupclient::RecvTransport::Listener {
|
||||
|
||||
public:
|
||||
Room *room;
|
||||
JNIEnv *env;
|
||||
jobject routerCallback;
|
||||
Room* room;
|
||||
|
||||
public:
|
||||
RecvListener(Room *room, JNIEnv *env, jobject routerCallback) {
|
||||
RecvListener(Room* room) {
|
||||
this->room = room;
|
||||
this->env = env;
|
||||
this->routerCallback = routerCallback;
|
||||
}
|
||||
|
||||
std::future<void> OnConnect(mediasoupclient::Transport *transport, const nlohmann::json &dtlsParameters) override {
|
||||
jclass jCallbackClazz = this->env->GetObjectClass(this->routerCallback);
|
||||
jmethodID recvTransportConnectCallback = this->env->GetMethodID(jCallbackClazz, "recvTransportConnectCallback", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
const char *cTransportId = transport->GetId().data();
|
||||
jstring jTransportId = this-> env->NewStringUTF(cTransportId);
|
||||
const char *cDtlsParameters = dtlsParameters.dump().data();
|
||||
jstring jDtlsParameters = this-> env->NewStringUTF(cDtlsParameters);
|
||||
this->env->CallVoidMethod(
|
||||
this->routerCallback,
|
||||
recvTransportConnectCallback,
|
||||
jTransportId,
|
||||
jDtlsParameters
|
||||
);
|
||||
this-> env->DeleteLocalRef(jTransportId);
|
||||
this-> env->ReleaseStringUTFChars(jTransportId, cTransportId);
|
||||
this-> env->DeleteLocalRef(jDtlsParameters);
|
||||
this-> env->ReleaseStringUTFChars(jDtlsParameters, cDtlsParameters);
|
||||
this-> env->DeleteLocalRef(jCallbackClazz);
|
||||
virtual ~RecvListener() {
|
||||
}
|
||||
|
||||
std::future<void> OnConnect(mediasoupclient::Transport* transport, const nlohmann::json& dtlsParameters) override {
|
||||
const std::string cTransportId = transport->GetId();
|
||||
const std::string cDtlsParameters = dtlsParameters.dump();
|
||||
this->room->recvTransportConnectCallback(cTransportId, cDtlsParameters);
|
||||
return std::future<void>();
|
||||
}
|
||||
|
||||
void OnConnectionStateChange(mediasoupclient::Transport *transport, const std::string &connectionState) override {
|
||||
void OnConnectionStateChange(mediasoupclient::Transport* transport, const std::string& connectionState) override {
|
||||
// 状态变化
|
||||
}
|
||||
|
||||
@@ -126,18 +72,17 @@ namespace acgist {
|
||||
class ProducerListener : public mediasoupclient::Producer::Listener {
|
||||
|
||||
public:
|
||||
Room *room;
|
||||
JNIEnv *env;
|
||||
jobject routerCallback;
|
||||
Room* room;
|
||||
|
||||
public:
|
||||
ProducerListener(Room *room, JNIEnv *env, jobject routerCallback) {
|
||||
ProducerListener(Room* room) {
|
||||
this->room = room;
|
||||
this->env = env;
|
||||
this->routerCallback = routerCallback;
|
||||
}
|
||||
|
||||
void OnTransportClose(mediasoupclient::Producer *producer) override {
|
||||
virtual ~ProducerListener() {
|
||||
}
|
||||
|
||||
void OnTransportClose(mediasoupclient::Producer* producer) override {
|
||||
|
||||
}
|
||||
|
||||
@@ -146,18 +91,17 @@ namespace acgist {
|
||||
class ConsumerListener : public mediasoupclient::Consumer::Listener {
|
||||
|
||||
public:
|
||||
Room *room;
|
||||
JNIEnv *env;
|
||||
jobject routerCallback;
|
||||
Room* room;
|
||||
|
||||
public:
|
||||
ConsumerListener(Room *room, JNIEnv *env, jobject routerCallback) {
|
||||
ConsumerListener(Room* room) {
|
||||
this->room = room;
|
||||
this->env = env;
|
||||
this->routerCallback = routerCallback;
|
||||
}
|
||||
|
||||
void OnTransportClose(mediasoupclient::Consumer *consumer) override {
|
||||
virtual ~ConsumerListener() {
|
||||
}
|
||||
|
||||
void OnTransportClose(mediasoupclient::Consumer* consumer) override {
|
||||
|
||||
}
|
||||
|
||||
@@ -165,17 +109,17 @@ namespace acgist {
|
||||
|
||||
Room::Room(
|
||||
std::string roomId,
|
||||
JNIEnv *env,
|
||||
JNIEnv* env,
|
||||
jobject routerCallback
|
||||
) {
|
||||
this->roomId = roomId;
|
||||
this->env = env;
|
||||
this->routerCallback = routerCallback;
|
||||
this->device = new mediasoupclient::Device();
|
||||
this->sendListener = new SendListener(this, env, routerCallback);
|
||||
this->recvListener = new RecvListener(this, env, routerCallback);
|
||||
this->producerListener = new ProducerListener(this, env, routerCallback);
|
||||
this->consumerListener = new ConsumerListener(this, env, routerCallback);
|
||||
this->sendListener = new SendListener(this);
|
||||
this->recvListener = new RecvListener(this);
|
||||
this->producerListener = new ProducerListener(this);
|
||||
this->consumerListener = new ConsumerListener(this);
|
||||
}
|
||||
|
||||
Room::~Room() {
|
||||
@@ -188,22 +132,25 @@ namespace acgist {
|
||||
delete this->videoProducer;
|
||||
delete this->producerListener;
|
||||
delete this->consumerListener;
|
||||
this-> env->DeleteLocalRef(this->routerCallback);
|
||||
this-> env->DeleteGlobalRef(this->routerCallback);
|
||||
this->env->DeleteLocalRef(this->routerCallback);
|
||||
this->env->DeleteGlobalRef(this->routerCallback);
|
||||
}
|
||||
|
||||
void Room::enter(
|
||||
std::string rtpCapabilities,
|
||||
webrtc::PeerConnectionFactoryInterface *factory,
|
||||
webrtc::PeerConnectionInterface::RTCConfiguration &rtcConfiguration
|
||||
webrtc::PeerConnectionFactoryInterface* factory,
|
||||
webrtc::PeerConnectionInterface::RTCConfiguration& rtcConfiguration
|
||||
) {
|
||||
nlohmann::json json;
|
||||
// TODO:全局
|
||||
mediasoupclient::PeerConnection::Options options;
|
||||
options.config = rtcConfiguration;
|
||||
options.config = rtcConfiguration;
|
||||
options.factory = factory;
|
||||
json["routerRtpCapabilities"] = nlohmann::json::parse(rtpCapabilities);
|
||||
this->device->Load(json, &options);
|
||||
const std::string cRtpCapabilities = this->device->GetRtpCapabilities().dump();
|
||||
const std::string cSctpCapabilities = this->device->GetSctpCapabilities().dump();
|
||||
this->enterCallback(cRtpCapabilities, cSctpCapabilities);
|
||||
}
|
||||
|
||||
void Room::createSendTransport(std::string body) {
|
||||
@@ -232,7 +179,7 @@ namespace acgist {
|
||||
);
|
||||
}
|
||||
|
||||
void Room::mediaProduceAudio(webrtc::MediaStreamInterface *mediaStream) {
|
||||
void Room::mediaProduceAudio(webrtc::MediaStreamInterface* mediaStream) {
|
||||
if(!this->device->CanProduce("audio")) {
|
||||
return;
|
||||
}
|
||||
@@ -250,7 +197,7 @@ namespace acgist {
|
||||
);
|
||||
}
|
||||
|
||||
void Room::mediaProduceVideo(webrtc::MediaStreamInterface *mediaStream) {
|
||||
void Room::mediaProduceVideo(webrtc::MediaStreamInterface* mediaStream) {
|
||||
if(this->device->CanProduce("video")) {
|
||||
return;
|
||||
}
|
||||
@@ -288,7 +235,7 @@ namespace acgist {
|
||||
void Room::mediaConsume(std::string message) {
|
||||
nlohmann::json json = nlohmann::json::parse(message);
|
||||
nlohmann::json body = json["body"];
|
||||
mediasoupclient::Consumer *consumer = this->recvTransport->Consume(
|
||||
mediasoupclient::Consumer* consumer = this->recvTransport->Consume(
|
||||
this->consumerListener,
|
||||
body["consumerId"],
|
||||
body["producerId"],
|
||||
@@ -297,23 +244,28 @@ namespace acgist {
|
||||
);
|
||||
this->consumers.insert({ consumer->GetId(), consumer });
|
||||
webrtc::MediaStreamTrackInterface* trackPointer = consumer->GetTrack();
|
||||
jclass jCallbackClazz = this->env->GetObjectClass(this->routerCallback);
|
||||
jmethodID consumerNewCallback = this->env->GetMethodID(jCallbackClazz, "consumerNewCallback", "(Ljava/lang/String;J;)V");
|
||||
const char *cMessage = message.data();
|
||||
jstring jMessage = this-> env->NewStringUTF(cMessage);
|
||||
this->env->CallVoidMethod(
|
||||
this->routerCallback,
|
||||
consumerNewCallback,
|
||||
jMessage,
|
||||
(jlong) trackPointer
|
||||
);
|
||||
this-> env->DeleteLocalRef(jMessage);
|
||||
this-> env->ReleaseStringUTFChars(jMessage, cMessage);
|
||||
this-> env->DeleteLocalRef(jCallbackClazz);
|
||||
this->consumerNewCallback(message, trackPointer);
|
||||
};
|
||||
|
||||
void Room::mediaProducerPause(std::string producerId) {
|
||||
}
|
||||
|
||||
void Room::mediaProducerResume(std::string producerId) {
|
||||
}
|
||||
|
||||
void Room::mediaProducerClose(std::string producerId) {
|
||||
}
|
||||
|
||||
void Room::mediaConsumerPause(std::string consumerId) {
|
||||
}
|
||||
|
||||
void Room::mediaConsumerResume(std::string consumerId) {
|
||||
}
|
||||
|
||||
void Room::mediaConsumerClose(std::string consumerId) {
|
||||
}
|
||||
|
||||
void Room::close() {
|
||||
delete this->device;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -327,123 +279,130 @@ namespace acgist {
|
||||
// TODO:为什么不能转换?测试是否因为stun配置问题
|
||||
webrtc::JavaParamRef<jobject> jRtcConfigurationRef(jRtcConfiguration);
|
||||
// webrtc::jni::JavaToNativeMediaConstraints()
|
||||
webrtc::jni::JavaToNativeRTCConfiguration(env, jRtcConfigurationRef, &rtcConfiguration);
|
||||
const char* rtpCapabilities = env->GetStringUTFChars(jRtpCapabilities, 0);
|
||||
// webrtc::jni::JavaToNativeRTCConfiguration(env, jRtcConfigurationRef, &rtcConfiguration);
|
||||
const char* rtpCapabilities = env->GetStringUTFChars(jRtpCapabilities, nullptr);
|
||||
room->enter(
|
||||
rtpCapabilities,
|
||||
reinterpret_cast<webrtc::PeerConnectionFactoryInterface*>(factoryPointer),
|
||||
// (webrtc::PeerConnectionFactoryInterface*) factoryPointer,
|
||||
rtcConfiguration
|
||||
);
|
||||
env->ReleaseStringUTFChars(jRtpCapabilities, rtpCapabilities);
|
||||
env->DeleteLocalRef(jRtpCapabilities);
|
||||
env->ReleaseStringUTFChars(jRtpCapabilities, rtpCapabilities);
|
||||
env->DeleteLocalRef(jRtcConfiguration);
|
||||
// delete rtpCapabilities;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeNewRoom(
|
||||
JNIEnv *env, jobject me,
|
||||
JNIEnv* env, jobject me,
|
||||
jstring jRoomId, jobject jRouterCallback
|
||||
) {
|
||||
const char* roomId = env->GetStringUTFChars(jRoomId, 0);
|
||||
jobject routerCallback = env->NewGlobalRef(jRouterCallback);
|
||||
const char* roomId = env->GetStringUTFChars(jRoomId, nullptr);
|
||||
Room* room = new Room(roomId, env, routerCallback);
|
||||
env->DeleteLocalRef(jRoomId);
|
||||
env->ReleaseStringUTFChars(jRoomId, roomId);
|
||||
return (jlong) room;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeCloseRoom(JNIEnv *env, jobject me, jlong nativeRoomPointer) {
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeCloseRoom(JNIEnv* env, jobject me, jlong nativeRoomPointer) {
|
||||
Room* room = (Room*) nativeRoomPointer;
|
||||
room->close();
|
||||
delete room;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeCreateSendTransport(JNIEnv *env, jobject me, jlong nativeRoomPointer, jstring jBody) {
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeCreateSendTransport(JNIEnv* env, jobject me, jlong nativeRoomPointer, jstring jBody) {
|
||||
Room* room = (Room*) nativeRoomPointer;
|
||||
const char* body = env->GetStringUTFChars(jBody, 0);
|
||||
const char* body = env->GetStringUTFChars(jBody, nullptr);
|
||||
room->createSendTransport(body);
|
||||
env->DeleteLocalRef(jBody);
|
||||
env->ReleaseStringUTFChars(jBody, body);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeCreateRecvTransport(JNIEnv *env, jobject me, jlong nativeRoomPointer, jstring jBody) {
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeCreateRecvTransport(JNIEnv* env, jobject me, jlong nativeRoomPointer, jstring jBody) {
|
||||
Room* room = (Room*) nativeRoomPointer;
|
||||
const char* body = env->GetStringUTFChars(jBody, 0);
|
||||
const char* body = env->GetStringUTFChars(jBody, nullptr);
|
||||
room->createRecvTransport(body);
|
||||
env->DeleteLocalRef(jBody);
|
||||
env->ReleaseStringUTFChars(jBody, body);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaProduceAudio(JNIEnv *env, jobject me, jlong nativeRoomPointer, jlong mediaStreamPointer) {
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaProduceAudio(JNIEnv* env, jobject me, jlong nativeRoomPointer, jlong mediaStreamPointer) {
|
||||
Room* room = (Room*) nativeRoomPointer;
|
||||
webrtc::MediaStreamInterface *mediaStream = reinterpret_cast<webrtc::MediaStreamInterface*>(mediaStreamPointer);
|
||||
webrtc::MediaStreamInterface* mediaStream = reinterpret_cast<webrtc::MediaStreamInterface*>(mediaStreamPointer);
|
||||
room->mediaProduceAudio(mediaStream);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaProduceVideo(JNIEnv *env, jobject me, jlong nativeRoomPointer, jlong mediaStreamPointer) {
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaProduceVideo(JNIEnv* env, jobject me, jlong nativeRoomPointer, jlong mediaStreamPointer) {
|
||||
Room* room = (Room*) nativeRoomPointer;
|
||||
webrtc::MediaStreamInterface *mediaStream = reinterpret_cast<webrtc::MediaStreamInterface*>(mediaStreamPointer);
|
||||
webrtc::MediaStreamInterface* mediaStream = reinterpret_cast<webrtc::MediaStreamInterface*>(mediaStreamPointer);
|
||||
room->mediaProduceVideo(mediaStream);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaConsume(JNIEnv *env, jobject me, jlong nativeRoomPointer, jstring jMessage) {
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaConsume(JNIEnv* env, jobject me, jlong nativeRoomPointer, jstring jMessage) {
|
||||
Room* room = (Room*) nativeRoomPointer;
|
||||
const char *message = env->GetStringUTFChars(jMessage, 0);
|
||||
const char* message = env->GetStringUTFChars(jMessage, nullptr);
|
||||
room->mediaConsume(message);
|
||||
env->DeleteLocalRef(jMessage);
|
||||
env->ReleaseStringUTFChars(jMessage, message);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaProducerPause(JNIEnv *env, jobject me, jlong nativeRoomPointer, jstring jProducerId) {
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaProducerPause(JNIEnv* env, jobject me, jlong nativeRoomPointer, jstring jProducerId) {
|
||||
Room* room = (Room*) nativeRoomPointer;
|
||||
const char *producerId = env->GetStringUTFChars(jProducerId, 0);
|
||||
const char* producerId = env->GetStringUTFChars(jProducerId, nullptr);
|
||||
room->mediaProducerPause(producerId);
|
||||
env->DeleteLocalRef(jProducerId);
|
||||
env->ReleaseStringUTFChars(jProducerId, producerId);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaProducerResume(JNIEnv *env, jobject me, jlong nativeRoomPointer, jstring jProducerId) {
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaProducerResume(JNIEnv* env, jobject me, jlong nativeRoomPointer, jstring jProducerId) {
|
||||
Room* room = (Room*) nativeRoomPointer;
|
||||
const char *producerId = env->GetStringUTFChars(jProducerId, 0);
|
||||
const char* producerId = env->GetStringUTFChars(jProducerId, nullptr);
|
||||
room->mediaProducerResume(producerId);
|
||||
env->DeleteLocalRef(jProducerId);
|
||||
env->ReleaseStringUTFChars(jProducerId, producerId);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaProducerClose(JNIEnv *env, jobject me, jlong nativeRoomPointer, jstring jProducerId) {
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaProducerClose(JNIEnv* env, jobject me, jlong nativeRoomPointer, jstring jProducerId) {
|
||||
Room* room = (Room*) nativeRoomPointer;
|
||||
const char *producerId = env->GetStringUTFChars(jProducerId, 0);
|
||||
const char* producerId = env->GetStringUTFChars(jProducerId, nullptr);
|
||||
room->mediaProducerClose(producerId);
|
||||
env->DeleteLocalRef(jProducerId);
|
||||
env->ReleaseStringUTFChars(jProducerId, producerId);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaConsumerPause(JNIEnv *env, jobject me, jlong nativeRoomPointer, jstring jConsumerId) {
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaConsumerPause(JNIEnv* env, jobject me, jlong nativeRoomPointer, jstring jConsumerId) {
|
||||
Room* room = (Room*) nativeRoomPointer;
|
||||
const char *consumerId = env->GetStringUTFChars(jConsumerId, 0);
|
||||
const char* consumerId = env->GetStringUTFChars(jConsumerId, nullptr);
|
||||
room->mediaConsumerPause(consumerId);
|
||||
env->DeleteLocalRef(jConsumerId);
|
||||
env->ReleaseStringUTFChars(jConsumerId, consumerId);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaConsumerResume(JNIEnv *env, jobject me, jlong nativeRoomPointer, jstring jConsumerId) {
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaConsumerResume(JNIEnv* env, jobject me, jlong nativeRoomPointer, jstring jConsumerId) {
|
||||
Room* room = (Room*) nativeRoomPointer;
|
||||
const char *consumerId = env->GetStringUTFChars(jConsumerId, 0);
|
||||
const char* consumerId = env->GetStringUTFChars(jConsumerId, nullptr);
|
||||
room->mediaConsumerResume(consumerId);
|
||||
env->DeleteLocalRef(jConsumerId);
|
||||
env->ReleaseStringUTFChars(jConsumerId, consumerId);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaConsumerClose(JNIEnv *env, jobject me, jlong nativeRoomPointer, jstring jConsumerId) {
|
||||
Java_com_acgist_taoyao_media_client_Room_nativeMediaConsumerClose(JNIEnv* env, jobject me, jlong nativeRoomPointer, jstring jConsumerId) {
|
||||
Room* room = (Room*) nativeRoomPointer;
|
||||
const char *consumerId = env->GetStringUTFChars(jConsumerId, 0);
|
||||
const char* consumerId = env->GetStringUTFChars(jConsumerId, nullptr);
|
||||
room->mediaConsumerClose(consumerId);
|
||||
env->DeleteLocalRef(jConsumerId);
|
||||
env->ReleaseStringUTFChars(jConsumerId, consumerId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#include "RouterCallback.hpp"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
void RouterCallback::enterCallback(std::string rtpCapabilities, std::string sctpCapabilities) {
|
||||
jclass jCallbackClazz = this->env->GetObjectClass(this->routerCallback);
|
||||
jmethodID recvTransportConnectCallback = this->env->GetMethodID(jCallbackClazz, "enterCallback", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
const char* cRtpCapabilities = rtpCapabilities.data();
|
||||
const char* cSctpCapabilities = sctpCapabilities.data();
|
||||
jstring jRtpCapabilities = this->env->NewStringUTF(cRtpCapabilities);
|
||||
jstring jScrpCapabilities = this->env->NewStringUTF(cSctpCapabilities);
|
||||
this->env->CallVoidMethod(
|
||||
this->routerCallback,
|
||||
recvTransportConnectCallback,
|
||||
jRtpCapabilities,
|
||||
jScrpCapabilities
|
||||
);
|
||||
this->env->DeleteLocalRef(jRtpCapabilities);
|
||||
this->env->DeleteLocalRef(jScrpCapabilities);
|
||||
this->env->DeleteLocalRef(jCallbackClazz);
|
||||
}
|
||||
|
||||
void RouterCallback::sendTransportConnectCallback(std::string transportId, std::string dtlsParameters) {
|
||||
jclass jCallbackClazz = this->env->GetObjectClass(this->routerCallback);
|
||||
jmethodID sendTransportConnectCallback = this->env->GetMethodID(jCallbackClazz, "sendTransportConnectCallback", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
const char* cTransportId = transportId.data();
|
||||
const char* cDtlsParameters = dtlsParameters.data();
|
||||
jstring jTransportId = this->env->NewStringUTF(cTransportId);
|
||||
jstring jDtlsParameters = this->env->NewStringUTF(cDtlsParameters);
|
||||
this->env->CallVoidMethod(
|
||||
this->routerCallback,
|
||||
sendTransportConnectCallback,
|
||||
jTransportId,
|
||||
jDtlsParameters
|
||||
);
|
||||
this->env->DeleteLocalRef(jTransportId);
|
||||
this->env->DeleteLocalRef(jDtlsParameters);
|
||||
this->env->DeleteLocalRef(jCallbackClazz);
|
||||
}
|
||||
|
||||
std::string RouterCallback::sendTransportProduceCallback(std::string kind, std::string transportId, std::string rtpParameters) {
|
||||
jclass jCallbackClazz = this->env->GetObjectClass(this->routerCallback);
|
||||
jmethodID sendTransportProduceCallback = this->env->GetMethodID(jCallbackClazz, "sendTransportProduceCallback", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
const char* cKind = kind.data();
|
||||
const char* cTransportId = transportId.data();
|
||||
const char* cRtpParameters = rtpParameters.data();
|
||||
jstring jKind = this->env->NewStringUTF(cKind);
|
||||
jstring jTransportId = this->env->NewStringUTF(cTransportId);
|
||||
jstring jRtpParameters = this->env->NewStringUTF(cRtpParameters);
|
||||
jstring jResult = (jstring) this->env->CallObjectMethod(
|
||||
this->routerCallback,
|
||||
sendTransportProduceCallback,
|
||||
jKind,
|
||||
jTransportId,
|
||||
jRtpParameters
|
||||
);
|
||||
const char* result = this->env->GetStringUTFChars(jResult, nullptr);
|
||||
this->env->DeleteLocalRef(jResult);
|
||||
this->env->ReleaseStringUTFChars(jResult, result);
|
||||
this->env->DeleteLocalRef(jKind);
|
||||
this->env->DeleteLocalRef(jTransportId);
|
||||
this->env->DeleteLocalRef(jRtpParameters);
|
||||
this->env->DeleteLocalRef(jCallbackClazz);
|
||||
return result;
|
||||
}
|
||||
|
||||
void RouterCallback::recvTransportConnectCallback(std::string transportId, std::string dtlsParameters) {
|
||||
jclass jCallbackClazz = this->env->GetObjectClass(this->routerCallback);
|
||||
jmethodID recvTransportConnectCallback = this->env->GetMethodID(jCallbackClazz, "recvTransportConnectCallback", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
const char* cTransportId = transportId.data();
|
||||
const char* cDtlsParameters = dtlsParameters.data();
|
||||
jstring jTransportId = this->env->NewStringUTF(cTransportId);
|
||||
jstring jDtlsParameters = this->env->NewStringUTF(cDtlsParameters);
|
||||
this->env->CallVoidMethod(
|
||||
this->routerCallback,
|
||||
recvTransportConnectCallback,
|
||||
jTransportId,
|
||||
jDtlsParameters
|
||||
);
|
||||
this->env->DeleteLocalRef(jTransportId);
|
||||
this->env->DeleteLocalRef(jDtlsParameters);
|
||||
this->env->DeleteLocalRef(jCallbackClazz);
|
||||
}
|
||||
|
||||
void RouterCallback::consumerNewCallback(std::string message, webrtc::MediaStreamTrackInterface* consumerMediaTrackPointer) {
|
||||
jclass jCallbackClazz = this->env->GetObjectClass(this->routerCallback);
|
||||
jmethodID consumerNewCallback = this->env->GetMethodID(jCallbackClazz, "consumerNewCallback", "(Ljava/lang/String;J;)V");
|
||||
const char* cMessage = message.data();
|
||||
jstring jMessage = this->env->NewStringUTF(cMessage);
|
||||
this->env->CallVoidMethod(
|
||||
this->routerCallback,
|
||||
consumerNewCallback,
|
||||
jMessage,
|
||||
(jlong) consumerMediaTrackPointer
|
||||
);
|
||||
this->env->DeleteLocalRef(jMessage);
|
||||
this->env->DeleteLocalRef(jCallbackClazz);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -106,10 +106,6 @@ public final class MediaManager {
|
||||
* 当前终端数量
|
||||
*/
|
||||
private volatile int clientCount;
|
||||
/**
|
||||
* 是否预览视频
|
||||
*/
|
||||
private boolean preview;
|
||||
/**
|
||||
* 是否打开音频播放
|
||||
*/
|
||||
@@ -166,10 +162,13 @@ public final class MediaManager {
|
||||
* 媒体流:声音、视频
|
||||
*/
|
||||
private MediaStream mediaStream;
|
||||
private AudioSource audioSource;
|
||||
private VideoSource videoSource;
|
||||
/**
|
||||
* 视频捕获
|
||||
*/
|
||||
private VideoCapturer videoCapturer;
|
||||
private SurfaceTextureHelper surfaceTextureHelper;
|
||||
/**
|
||||
* PeerConnectionFactory
|
||||
*/
|
||||
@@ -190,14 +189,14 @@ public final class MediaManager {
|
||||
for (MediaCodecInfo mediaCodecInfo : mediaCodecList.getCodecInfos()) {
|
||||
// if (mediaCodecInfo.isEncoder()) {
|
||||
final String[] supportedTypes = mediaCodecInfo.getSupportedTypes();
|
||||
Log.d(RecordClient.class.getSimpleName(), "编码器名称:" + mediaCodecInfo.getName());
|
||||
Log.d(RecordClient.class.getSimpleName(), "编码器类型:" + String.join(" , ", supportedTypes));
|
||||
Log.d(MediaManager.class.getSimpleName(), "编码器名称:" + mediaCodecInfo.getName());
|
||||
Log.d(MediaManager.class.getSimpleName(), "编码器类型:" + String.join(" , ", supportedTypes));
|
||||
for (String supportType : supportedTypes) {
|
||||
final MediaCodecInfo.CodecCapabilities codecCapabilities = mediaCodecInfo.getCapabilitiesForType(supportType);
|
||||
final int[] colorFormats = codecCapabilities.colorFormats;
|
||||
Log.d(RecordClient.class.getSimpleName(), "编码器格式:" + codecCapabilities.getMimeType());
|
||||
Log.d(MediaManager.class.getSimpleName(), "编码器支持的文件格式:" + codecCapabilities.getMimeType());
|
||||
// MediaCodecInfo.CodecCapabilities.COLOR_*
|
||||
Log.d(RecordClient.class.getSimpleName(), "编码器支持格式:" + IntStream.of(colorFormats).boxed().map(String::valueOf).collect(Collectors.joining(" , ")));
|
||||
// final int[] colorFormats = codecCapabilities.colorFormats;
|
||||
// Log.d(MediaManager.class.getSimpleName(), "编码器支持的色彩格式:" + IntStream.of(colorFormats).boxed().map(String::valueOf).collect(Collectors.joining(" , ")));
|
||||
}
|
||||
// }
|
||||
}
|
||||
@@ -210,7 +209,6 @@ public final class MediaManager {
|
||||
/**
|
||||
* @param handler Handler
|
||||
* @param context 上下文
|
||||
* @param preview 是否预览视频
|
||||
* @param playAudio 是否播放音频
|
||||
* @param playVideo 是否播放视频
|
||||
* @param audioConsume 是否消费音频
|
||||
@@ -220,14 +218,13 @@ public final class MediaManager {
|
||||
*/
|
||||
public void initContext(
|
||||
Handler handler, Context context,
|
||||
boolean preview, boolean playAudio, boolean playVideo,
|
||||
boolean playAudio, boolean playVideo,
|
||||
boolean audioConsume, boolean videoConsume,
|
||||
boolean audioProduce, boolean videoProduce,
|
||||
TransportType transportType
|
||||
) {
|
||||
this.handler = handler;
|
||||
this.context = context;
|
||||
this.preview = preview;
|
||||
this.playAudio = playAudio;
|
||||
this.playVideo = playVideo;
|
||||
this.audioConsume = audioConsume;
|
||||
@@ -355,7 +352,7 @@ public final class MediaManager {
|
||||
.setVideoDecoderFactory(videoDecoderFactory)
|
||||
.setVideoEncoderFactory(videoEncoderFactory)
|
||||
.createPeerConnectionFactory();
|
||||
this.mediaStream = this.peerConnectionFactory.createLocalMediaStream("ARDAMS");
|
||||
this.mediaStream = this.peerConnectionFactory.createLocalMediaStream("Taoyao");
|
||||
Arrays.stream(videoEncoderFactory.getSupportedCodecs()).forEach(v -> {
|
||||
Log.d(MediaManager.class.getSimpleName(), "支持的视频解码器:" + v.name);
|
||||
});
|
||||
@@ -412,8 +409,8 @@ public final class MediaManager {
|
||||
mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googNoiseSuppression", "true"));
|
||||
// mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googNoiseSuppression2", "true"));
|
||||
// mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("googTypingNoiseDetection", "true"));
|
||||
final AudioSource audioSource = this.peerConnectionFactory.createAudioSource(mediaConstraints);
|
||||
final AudioTrack audioTrack = this.peerConnectionFactory.createAudioTrack("ARDAMSa0", audioSource);
|
||||
this.audioSource = this.peerConnectionFactory.createAudioSource(mediaConstraints);
|
||||
final AudioTrack audioTrack = this.peerConnectionFactory.createAudioTrack("TaoyaoA0", this.audioSource);
|
||||
// audioTrack.setVolume(100);
|
||||
audioTrack.setEnabled(true);
|
||||
this.mediaStream.addTrack(audioTrack);
|
||||
@@ -473,15 +470,15 @@ public final class MediaManager {
|
||||
*/
|
||||
private void initVideoTrack() {
|
||||
// 加载视频
|
||||
final SurfaceTextureHelper surfaceTextureHelper = SurfaceTextureHelper.create("MediaVideoThread", this.eglBase.getEglBaseContext());
|
||||
// surfaceTextureHelper.setTextureSize();
|
||||
// surfaceTextureHelper.setFrameRotation();
|
||||
final VideoSource videoSource = this.peerConnectionFactory.createVideoSource(this.videoCapturer.isScreencast());
|
||||
this.surfaceTextureHelper = SurfaceTextureHelper.create("MediaVideoThread", this.eglBase.getEglBaseContext());
|
||||
// this.surfaceTextureHelper.setTextureSize();
|
||||
// this.surfaceTextureHelper.setFrameRotation();
|
||||
this.videoSource = this.peerConnectionFactory.createVideoSource(this.videoCapturer.isScreencast());
|
||||
// 美颜水印
|
||||
// videoSource.setVideoProcessor();
|
||||
this.videoCapturer.initialize(surfaceTextureHelper, this.context, videoSource.getCapturerObserver());
|
||||
// this.videoSource.setVideoProcessor();
|
||||
this.videoCapturer.initialize(this.surfaceTextureHelper, this.context, this.videoSource.getCapturerObserver());
|
||||
this.videoCapturer.startCapture(480, 640, 30);
|
||||
final VideoTrack videoTrack = this.peerConnectionFactory.createVideoTrack("ARDAMSv0", videoSource);
|
||||
final VideoTrack videoTrack = this.peerConnectionFactory.createVideoTrack("TaoyaoV0", this.videoSource);
|
||||
videoTrack.addSink(videoFrame -> {
|
||||
if(this.recordClient != null) {
|
||||
this.recordClient.putVideo(videoFrame);
|
||||
@@ -492,17 +489,12 @@ public final class MediaManager {
|
||||
Log.i(MediaManager.class.getSimpleName(), "加载视频:" + videoTrack.id());
|
||||
}
|
||||
|
||||
public boolean isPreview() {
|
||||
return this.preview;
|
||||
}
|
||||
|
||||
public MediaStream getMediaStream() {
|
||||
return this.mediaStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param flag Config.WHAT_*
|
||||
* @param forceEnabled 是否强制播放
|
||||
* @param videoTrack 视频媒体流Track
|
||||
*
|
||||
* @return 播放控件
|
||||
@@ -575,8 +567,8 @@ public final class MediaManager {
|
||||
final Iterator<AudioTrack> iterator = this.mediaStream.audioTracks.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
track = iterator.next();
|
||||
iterator.remove();
|
||||
track.dispose();
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -585,9 +577,7 @@ public final class MediaManager {
|
||||
* 关闭视频
|
||||
*/
|
||||
private void closeVideoTrack() {
|
||||
// 次码流
|
||||
this.closeVideoTrack(this.mediaStream.videoTracks);
|
||||
// 主码流
|
||||
this.closeVideoTrack(this.mediaStream.preservedVideoTracks);
|
||||
}
|
||||
|
||||
@@ -602,8 +592,8 @@ public final class MediaManager {
|
||||
final Iterator<VideoTrack> iterator = list.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
track = iterator.next();
|
||||
iterator.remove();
|
||||
track.dispose();
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -618,14 +608,26 @@ public final class MediaManager {
|
||||
this.eglBase.release();
|
||||
this.eglBase = null;
|
||||
}
|
||||
if (this.videoCapturer != null) {
|
||||
this.videoCapturer.dispose();
|
||||
this.videoCapturer = null;
|
||||
if(this.audioSource != null) {
|
||||
this.audioSource.dispose();
|
||||
this.audioSource = null;
|
||||
}
|
||||
if(this.videoSource != null) {
|
||||
this.videoSource.dispose();
|
||||
this.videoSource = null;
|
||||
}
|
||||
if (this.mediaStream != null) {
|
||||
this.mediaStream.dispose();
|
||||
this.mediaStream = null;
|
||||
}
|
||||
if (this.videoCapturer != null) {
|
||||
this.videoCapturer.dispose();
|
||||
this.videoCapturer = null;
|
||||
}
|
||||
if(this.surfaceTextureHelper != null) {
|
||||
this.surfaceTextureHelper.dispose();
|
||||
this.surfaceTextureHelper = null;
|
||||
}
|
||||
if (this.peerConnectionFactory != null) {
|
||||
this.peerConnectionFactory.dispose();
|
||||
this.peerConnectionFactory = null;
|
||||
|
||||
@@ -13,7 +13,7 @@ public interface RouterCallback {
|
||||
default void sendTransportConnectCallback(String transportId, String dtlsParameters) {};
|
||||
default String sendTransportProduceCallback(String kind, String transportId, String rtpParameters) { return null; };
|
||||
default void recvTransportConnectCallback(String transportId, String dtlsParameters) {};
|
||||
default void producerNewCallback(String kind, String producerId, long producerMediaTrackPointer) { };
|
||||
default void producerNewCallback(String kind, String producerId, long producerMediaTrackPointer) {};
|
||||
default void producerPauseCallback(String producerId) {};
|
||||
default void producerResumeCallback(String producerId) {};
|
||||
default void producerCloseCallback(String producerId) {};
|
||||
|
||||
@@ -5,5 +5,6 @@ package com.acgist.taoyao.media.audio;
|
||||
*
|
||||
* @author acgist
|
||||
*/
|
||||
public class VoiceChangerProcesser {
|
||||
public class AudioChangerProcesser {
|
||||
|
||||
}
|
||||
@@ -36,6 +36,7 @@ public class Room extends CloseableClient implements RouterCallback {
|
||||
private final String clientId;
|
||||
private final String roomId;
|
||||
private final String password;
|
||||
private final boolean preview;
|
||||
private final boolean dataConsume;
|
||||
private final boolean audioConsume;
|
||||
private final boolean videoConsume;
|
||||
@@ -47,24 +48,27 @@ public class Room extends CloseableClient implements RouterCallback {
|
||||
private Map<String, RemoteClient> remoteClients;
|
||||
private PeerConnection.RTCConfiguration rtcConfiguration;
|
||||
private PeerConnectionFactory peerConnectionFactory;
|
||||
private String rtpCapabilities;
|
||||
private String sctpCapabilities;
|
||||
|
||||
public Room(
|
||||
String name, String clientId,
|
||||
String roomId, String password,
|
||||
ITaoyao taoyao, Handler handler,
|
||||
boolean preview,
|
||||
boolean dataConsume, boolean audioConsume, boolean videoConsume,
|
||||
boolean dataProduce, boolean audioProduce, boolean videoProduce
|
||||
) {
|
||||
super(taoyao, handler);
|
||||
this.name = name;
|
||||
this.clientId = clientId;
|
||||
this.roomId = roomId;
|
||||
this.roomId = roomId;
|
||||
this.password = password;
|
||||
this.dataConsume = dataConsume;
|
||||
this.preview = preview;
|
||||
this.dataConsume = dataConsume;
|
||||
this.audioConsume = audioConsume;
|
||||
this.videoConsume = videoConsume;
|
||||
this.dataProduce = dataProduce;
|
||||
this.dataProduce = dataProduce;
|
||||
this.audioProduce = audioProduce;
|
||||
this.videoProduce = videoProduce;
|
||||
this.nativeRoomPointer = this.nativeNewRoom(roomId, this);
|
||||
@@ -268,11 +272,13 @@ public class Room extends CloseableClient implements RouterCallback {
|
||||
|
||||
@Override
|
||||
public void enterCallback(String rtpCapabilities, String sctpCapabilities) {
|
||||
this.rtpCapabilities = rtpCapabilities;
|
||||
this.sctpCapabilities = sctpCapabilities;
|
||||
this.taoyao.request(this.taoyao.buildMessage(
|
||||
"room::enter",
|
||||
"roomId", this.roomId,
|
||||
"password", this.password,
|
||||
"rtpCapabilities", rtpCapabilities,
|
||||
"roomId", this.roomId,
|
||||
"password", this.password,
|
||||
"rtpCapabilities", rtpCapabilities,
|
||||
"sctpCapabilities", sctpCapabilities
|
||||
));
|
||||
}
|
||||
@@ -281,8 +287,8 @@ public class Room extends CloseableClient implements RouterCallback {
|
||||
public void sendTransportConnectCallback(String transportId, String dtlsParameters) {
|
||||
this.taoyao.request(this.taoyao.buildMessage(
|
||||
"media::transport::webrtc::connect",
|
||||
"roomId", this.roomId,
|
||||
"transportId", transportId,
|
||||
"roomId", this.roomId,
|
||||
"transportId", transportId,
|
||||
"dtlsParameters", JSONUtils.toMap(dtlsParameters)
|
||||
));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.acgist.taoyao.media.signal;
|
||||
|
||||
import com.acgist.taoyao.boot.model.Message;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 信令监听
|
||||
*
|
||||
* @author acgist
|
||||
*/
|
||||
public interface ITaoyaoListener {
|
||||
|
||||
/**
|
||||
* 前置信令处理
|
||||
*
|
||||
* @param message 信令消息
|
||||
*
|
||||
* @return 是否继续处理信令
|
||||
*/
|
||||
default boolean preOnMessage(Message message) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后置信令处理
|
||||
*
|
||||
* @param message 信令消息
|
||||
*/
|
||||
default void postOnMessage(Message message) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 信令正在连接
|
||||
*/
|
||||
default void onConnect() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 信令连接成功
|
||||
*/
|
||||
default void onConnected() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 信令断开连接
|
||||
*/
|
||||
default void onDisconnect() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 信令异常
|
||||
*
|
||||
* @param throwable 异常
|
||||
*/
|
||||
default void onError(Throwable throwable) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,9 +1,30 @@
|
||||
package com.acgist.taoyao.media.video;
|
||||
|
||||
import org.webrtc.VideoFrame;
|
||||
import org.webrtc.VideoProcessor;
|
||||
import org.webrtc.VideoSink;
|
||||
|
||||
/**
|
||||
* AI处理器
|
||||
*
|
||||
* @author acgist
|
||||
*/
|
||||
public class AiProcesser {
|
||||
public class AiProcesser implements VideoProcessor {
|
||||
|
||||
@Override
|
||||
public void setSink(VideoSink videoSink) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCapturerStarted(boolean status) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCapturerStopped() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFrameCaptured(VideoFrame videoFrame) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,29 @@
|
||||
package com.acgist.taoyao.media.video;
|
||||
|
||||
import org.webrtc.VideoFrame;
|
||||
import org.webrtc.VideoProcessor;
|
||||
import org.webrtc.VideoSink;
|
||||
|
||||
/**
|
||||
* 美颜处理器
|
||||
*
|
||||
* @author acgist
|
||||
*/
|
||||
public class BeautyProcesser {
|
||||
public class BeautyProcesser implements VideoProcessor {
|
||||
|
||||
@Override
|
||||
public void setSink(VideoSink videoSink) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCapturerStarted(boolean status) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCapturerStopped() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFrameCaptured(VideoFrame videoFrame) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,30 @@
|
||||
package com.acgist.taoyao.media.video;
|
||||
|
||||
import org.webrtc.VideoFrame;
|
||||
import org.webrtc.VideoProcessor;
|
||||
import org.webrtc.VideoSink;
|
||||
|
||||
/**
|
||||
* 水印处理器
|
||||
*
|
||||
* @author acgist
|
||||
*/
|
||||
public class WatermarkProcesser {
|
||||
public class WatermarkProcesser implements VideoProcessor {
|
||||
|
||||
@Override
|
||||
public void setSink(VideoSink videoSink) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCapturerStarted(boolean status) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCapturerStopped() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFrameCaptured(VideoFrame videoFrame) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user