[*] 每日优化
This commit is contained in:
@@ -24,7 +24,7 @@ wget /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.
|
|||||||
yum makecache
|
yum makecache
|
||||||
```
|
```
|
||||||
|
|
||||||
## 更新依赖
|
## 安装依赖
|
||||||
|
|
||||||
```
|
```
|
||||||
yum install zlib-devel libffi-devel openssl-devel
|
yum install zlib-devel libffi-devel openssl-devel
|
||||||
|
|||||||
0
docs/Docker.md
Normal file
0
docs/Docker.md
Normal file
@@ -34,6 +34,7 @@
|
|||||||
* 录制底噪
|
* 录制底噪
|
||||||
* 分辨率调整
|
* 分辨率调整
|
||||||
* 服务端录制
|
* 服务端录制
|
||||||
|
* 安卓预览按钮
|
||||||
* 降低视频录制大小
|
* 降低视频录制大小
|
||||||
* 防止重复邀请拉取
|
* 防止重复邀请拉取
|
||||||
* 查询消费者生产者信息
|
* 查询消费者生产者信息
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace acgist {
|
|||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_acgist_taoyao_media_MediaManager_nativeInit(JNIEnv* env, jobject me) {
|
Java_com_acgist_taoyao_media_MediaManager_nativeInit(JNIEnv* env, jobject me) {
|
||||||
std::string version = mediasoupclient::Version();
|
std::string version = mediasoupclient::Version();
|
||||||
LOG_I("加载MediasoupClient %s", version.data());
|
LOG_I("加载MediasoupClient:%s", version.data());
|
||||||
mediasoupclient::Initialize();
|
mediasoupclient::Initialize();
|
||||||
// => { spatialLayers: 2, temporalLayers: 3 }
|
// => { spatialLayers: 2, temporalLayers: 3 }
|
||||||
// mediasoupclient::parseScalabilityMode("L2T3");
|
// mediasoupclient::parseScalabilityMode("L2T3");
|
||||||
|
|||||||
@@ -2,22 +2,45 @@
|
|||||||
|
|
||||||
namespace acgist {
|
namespace acgist {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送通道监听器
|
||||||
|
*/
|
||||||
class SendListener : public mediasoupclient::SendTransport::Listener {
|
class SendListener : public mediasoupclient::SendTransport::Listener {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* 房间指针
|
||||||
|
*/
|
||||||
Room* room;
|
Room* room;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* 发送通道监听器
|
||||||
|
*
|
||||||
|
* @param room 房间指针
|
||||||
|
*/
|
||||||
explicit SendListener(Room* room) {
|
explicit SendListener(Room* room) {
|
||||||
this->room = room;
|
this->room = room;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 析构函数
|
||||||
|
*/
|
||||||
virtual ~SendListener() {
|
virtual ~SendListener() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* 连接通道
|
||||||
|
*
|
||||||
|
* @param transport 通道指针
|
||||||
|
* @param dtlsParameters DTLS参数
|
||||||
|
*
|
||||||
|
* @return future
|
||||||
|
*/
|
||||||
std::future<void> OnConnect(mediasoupclient::Transport* transport, const nlohmann::json& dtlsParameters) override {
|
std::future<void> OnConnect(mediasoupclient::Transport* transport, const nlohmann::json& dtlsParameters) override {
|
||||||
const std::string cTransportId = transport->GetId();
|
const std::string cTransportId = transport->GetId();
|
||||||
const std::string cDtlsParameters = dtlsParameters.dump();
|
const std::string cDtlsParameters = dtlsParameters.dump();
|
||||||
|
LOG_I("连接发送通道:%s - %s", this->room->roomId.data(), cTransportId.data());
|
||||||
JNIEnv* env = nullptr;
|
JNIEnv* env = nullptr;
|
||||||
if(taoyaoJavaVM->GetEnv((void**) &env, JNI_VERSION_1_6) == JNI_EDETACHED) {
|
if(taoyaoJavaVM->GetEnv((void**) &env, JNI_VERSION_1_6) == JNI_EDETACHED) {
|
||||||
bindJavaThread(&env);
|
bindJavaThread(&env);
|
||||||
@@ -31,13 +54,31 @@ namespace acgist {
|
|||||||
return promise.get_future();
|
return promise.get_future();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通道状态改变
|
||||||
|
*
|
||||||
|
* @param transport 通道指针
|
||||||
|
* @param connectionState 当前状态
|
||||||
|
*/
|
||||||
void OnConnectionStateChange(mediasoupclient::Transport* transport, const std::string& connectionState) override {
|
void OnConnectionStateChange(mediasoupclient::Transport* transport, const std::string& connectionState) override {
|
||||||
|
LOG_I("发送通道状态改变:%s - %s - %s", this->room->roomId.data(), transport->GetId().data(), connectionState.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通道生产媒体
|
||||||
|
*
|
||||||
|
* @param transport 通道指针
|
||||||
|
* @param kind 媒体类型
|
||||||
|
* @param rtpParameters RTP参数
|
||||||
|
* @param appData 应用数据
|
||||||
|
*
|
||||||
|
* @return 生产者ID
|
||||||
|
*/
|
||||||
std::future<std::string> OnProduce(mediasoupclient::SendTransport* transport, const std::string& kind, nlohmann::json rtpParameters, const nlohmann::json& appData) override {
|
std::future<std::string> OnProduce(mediasoupclient::SendTransport* transport, const std::string& kind, nlohmann::json rtpParameters, const nlohmann::json& appData) override {
|
||||||
std::string result;
|
std::string result;
|
||||||
const std::string cTransportId = transport->GetId();
|
const std::string cTransportId = transport->GetId();
|
||||||
const std::string cRtpParameters = rtpParameters.dump();
|
const std::string cRtpParameters = rtpParameters.dump();
|
||||||
|
LOG_I("生产媒体:%s - %s - %s", this->room->roomId.data(), cTransportId.data(), kind.data());
|
||||||
JNIEnv* env = nullptr;
|
JNIEnv* env = nullptr;
|
||||||
if(taoyaoJavaVM->GetEnv((void**) &env, JNI_VERSION_1_6) == JNI_EDETACHED) {
|
if(taoyaoJavaVM->GetEnv((void**) &env, JNI_VERSION_1_6) == JNI_EDETACHED) {
|
||||||
bindJavaThread(&env);
|
bindJavaThread(&env);
|
||||||
@@ -51,29 +92,65 @@ namespace acgist {
|
|||||||
return promise.get_future();
|
return promise.get_future();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通道生产数据
|
||||||
|
* 注意:需要自己实现
|
||||||
|
*
|
||||||
|
* @param transport 通道指针
|
||||||
|
* @param sctpStreamParameters SCTP参数
|
||||||
|
* @param label 标记
|
||||||
|
* @param protocol 协议
|
||||||
|
* @param appData 应用数据
|
||||||
|
*
|
||||||
|
* @return 生产者ID
|
||||||
|
*/
|
||||||
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 {
|
||||||
|
const std::string cTransportId = transport->GetId();
|
||||||
|
LOG_I("生产数据:%s - %s - %s -%s", this->room->roomId.data(), cTransportId.data(), label.data(), protocol.data());
|
||||||
std::promise <std::string> promise;
|
std::promise <std::string> promise;
|
||||||
// TODO:如果需要自行实现
|
|
||||||
return promise.get_future();
|
return promise.get_future();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接收通道监听器
|
||||||
|
*/
|
||||||
class RecvListener : public mediasoupclient::RecvTransport::Listener {
|
class RecvListener : public mediasoupclient::RecvTransport::Listener {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* 房间指针
|
||||||
|
*/
|
||||||
Room* room;
|
Room* room;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* 接收通道监听器
|
||||||
|
*
|
||||||
|
* @param room 房间指针
|
||||||
|
*/
|
||||||
explicit RecvListener(Room* room) {
|
explicit RecvListener(Room* room) {
|
||||||
this->room = room;
|
this->room = room;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 析构函数
|
||||||
|
*/
|
||||||
virtual ~RecvListener() {
|
virtual ~RecvListener() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接通道
|
||||||
|
*
|
||||||
|
* @param transport 通道指针
|
||||||
|
* @param dtlsParameters DTLS参数
|
||||||
|
*
|
||||||
|
* @return future
|
||||||
|
*/
|
||||||
std::future<void> OnConnect(mediasoupclient::Transport* transport, const nlohmann::json& dtlsParameters) override {
|
std::future<void> OnConnect(mediasoupclient::Transport* transport, const nlohmann::json& dtlsParameters) override {
|
||||||
const std::string cTransportId = transport->GetId();
|
const std::string cTransportId = transport->GetId();
|
||||||
const std::string cDtlsParameters = dtlsParameters.dump();
|
const std::string cDtlsParameters = dtlsParameters.dump();
|
||||||
|
LOG_I("连接接收通道:%s - %s", this->room->roomId.data(), cTransportId.data());
|
||||||
JNIEnv* env = nullptr;
|
JNIEnv* env = nullptr;
|
||||||
if(taoyaoJavaVM->GetEnv((void**) &env, JNI_VERSION_1_6) == JNI_EDETACHED) {
|
if(taoyaoJavaVM->GetEnv((void**) &env, JNI_VERSION_1_6) == JNI_EDETACHED) {
|
||||||
bindJavaThread(&env);
|
bindJavaThread(&env);
|
||||||
@@ -87,24 +164,51 @@ namespace acgist {
|
|||||||
return promise.get_future();
|
return promise.get_future();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通道状态改变
|
||||||
|
*
|
||||||
|
* @param transport 通道指针
|
||||||
|
* @param connectionState 通道状态
|
||||||
|
*/
|
||||||
void OnConnectionStateChange(mediasoupclient::Transport* transport, const std::string& connectionState) override {
|
void OnConnectionStateChange(mediasoupclient::Transport* transport, const std::string& connectionState) override {
|
||||||
|
LOG_I("接收通道状态改变:%s - %s - %s", this->room->roomId.data(), transport->GetId().data(), connectionState.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生产者监听器
|
||||||
|
*/
|
||||||
class ProducerListener : public mediasoupclient::Producer::Listener {
|
class ProducerListener : public mediasoupclient::Producer::Listener {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* 房间指针
|
||||||
|
*/
|
||||||
Room* room;
|
Room* room;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* 生产者监听器
|
||||||
|
*
|
||||||
|
* @param room 房间指针
|
||||||
|
*/
|
||||||
explicit ProducerListener(Room* room) {
|
explicit ProducerListener(Room* room) {
|
||||||
this->room = room;
|
this->room = room;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 析构函数
|
||||||
|
*/
|
||||||
virtual ~ProducerListener() {
|
virtual ~ProducerListener() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通道关闭
|
||||||
|
*
|
||||||
|
* @param producer 生产者
|
||||||
|
*/
|
||||||
void OnTransportClose(mediasoupclient::Producer* producer) override {
|
void OnTransportClose(mediasoupclient::Producer* producer) override {
|
||||||
|
LOG_I("生产者通道关闭:%s - %s", this->room->roomId.data(), producer->GetId().data());
|
||||||
producer->Close();
|
producer->Close();
|
||||||
JNIEnv* env = nullptr;
|
JNIEnv* env = nullptr;
|
||||||
if(taoyaoJavaVM->GetEnv((void**) &env, JNI_VERSION_1_6) == JNI_EDETACHED) {
|
if(taoyaoJavaVM->GetEnv((void**) &env, JNI_VERSION_1_6) == JNI_EDETACHED) {
|
||||||
@@ -118,20 +222,39 @@ namespace acgist {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消费者监听器
|
||||||
|
*/
|
||||||
class ConsumerListener : public mediasoupclient::Consumer::Listener {
|
class ConsumerListener : public mediasoupclient::Consumer::Listener {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* 房间指针
|
||||||
|
*/
|
||||||
Room* room;
|
Room* room;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* 消费者监听器
|
||||||
|
*
|
||||||
|
* @param room 房间指针
|
||||||
|
*/
|
||||||
explicit ConsumerListener(Room* room) {
|
explicit ConsumerListener(Room* room) {
|
||||||
this->room = room;
|
this->room = room;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 析构函数
|
||||||
|
*/
|
||||||
virtual ~ConsumerListener() {
|
virtual ~ConsumerListener() {
|
||||||
// mediasoupclient::Consumer::Listener::~Listener();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通道关闭
|
||||||
|
*
|
||||||
|
* @param consumer 消费者
|
||||||
|
*/
|
||||||
void OnTransportClose(mediasoupclient::Consumer* consumer) override {
|
void OnTransportClose(mediasoupclient::Consumer* consumer) override {
|
||||||
|
LOG_I("消费者通道关闭:%s - %s", this->room->roomId.data(), consumer->GetId().data());
|
||||||
consumer->Close();
|
consumer->Close();
|
||||||
JNIEnv* env = nullptr;
|
JNIEnv* env = nullptr;
|
||||||
if(taoyaoJavaVM->GetEnv((void**) &env, JNI_VERSION_1_6) == JNI_EDETACHED) {
|
if(taoyaoJavaVM->GetEnv((void**) &env, JNI_VERSION_1_6) == JNI_EDETACHED) {
|
||||||
@@ -164,6 +287,7 @@ namespace acgist {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Room::~Room() {
|
Room::~Room() {
|
||||||
|
// TODO:解决析构函数不是虚函数的问题
|
||||||
delete this->rtcConfiguration;
|
delete this->rtcConfiguration;
|
||||||
delete this->device;
|
delete this->device;
|
||||||
delete this->sendListener;
|
delete this->sendListener;
|
||||||
@@ -185,8 +309,8 @@ namespace acgist {
|
|||||||
this->factory = factory;
|
this->factory = factory;
|
||||||
this->rtcConfiguration = new webrtc::PeerConnectionInterface::RTCConfiguration(rtcConfiguration);
|
this->rtcConfiguration = new webrtc::PeerConnectionInterface::RTCConfiguration(rtcConfiguration);
|
||||||
mediasoupclient::PeerConnection::Options options;
|
mediasoupclient::PeerConnection::Options options;
|
||||||
options.config = rtcConfiguration;
|
options.config = rtcConfiguration;
|
||||||
options.factory = factory;
|
options.factory = factory;
|
||||||
nlohmann::json json = nlohmann::json::parse(rtpCapabilities);
|
nlohmann::json json = nlohmann::json::parse(rtpCapabilities);
|
||||||
this->device->Load(json, &options);
|
this->device->Load(json, &options);
|
||||||
const std::string cRtpCapabilities = this->device->GetRtpCapabilities().dump();
|
const std::string cRtpCapabilities = this->device->GetRtpCapabilities().dump();
|
||||||
@@ -197,8 +321,8 @@ namespace acgist {
|
|||||||
void Room::createSendTransport(JNIEnv* env, const std::string& body) {
|
void Room::createSendTransport(JNIEnv* env, const std::string& body) {
|
||||||
nlohmann::json json = nlohmann::json::parse(body);
|
nlohmann::json json = nlohmann::json::parse(body);
|
||||||
mediasoupclient::PeerConnection::Options options;
|
mediasoupclient::PeerConnection::Options options;
|
||||||
options.config = *this->rtcConfiguration;
|
options.config = *this->rtcConfiguration;
|
||||||
options.factory = this->factory;
|
options.factory = this->factory;
|
||||||
this->sendTransport = this->device->CreateSendTransport(
|
this->sendTransport = this->device->CreateSendTransport(
|
||||||
this->sendListener,
|
this->sendListener,
|
||||||
json["transportId"],
|
json["transportId"],
|
||||||
@@ -213,8 +337,8 @@ namespace acgist {
|
|||||||
void Room::createRecvTransport(JNIEnv* env, const std::string& body) {
|
void Room::createRecvTransport(JNIEnv* env, const std::string& body) {
|
||||||
nlohmann::json json = nlohmann::json::parse(body);
|
nlohmann::json json = nlohmann::json::parse(body);
|
||||||
mediasoupclient::PeerConnection::Options options;
|
mediasoupclient::PeerConnection::Options options;
|
||||||
options.config = *this->rtcConfiguration;
|
options.config = *this->rtcConfiguration;
|
||||||
options.factory = this->factory;
|
options.factory = this->factory;
|
||||||
this->recvTransport = this->device->CreateRecvTransport(
|
this->recvTransport = this->device->CreateRecvTransport(
|
||||||
this->recvListener,
|
this->recvListener,
|
||||||
json["transportId"],
|
json["transportId"],
|
||||||
@@ -228,6 +352,7 @@ namespace acgist {
|
|||||||
|
|
||||||
void Room::mediaProduceAudio(JNIEnv* env, webrtc::MediaStreamInterface* mediaStream) {
|
void Room::mediaProduceAudio(JNIEnv* env, webrtc::MediaStreamInterface* mediaStream) {
|
||||||
if(!this->device->CanProduce("audio")) {
|
if(!this->device->CanProduce("audio")) {
|
||||||
|
LOG_I("不能生产音频媒体:%s", this->roomId.data());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nlohmann::json codecOptions =
|
nlohmann::json codecOptions =
|
||||||
@@ -247,13 +372,17 @@ namespace acgist {
|
|||||||
|
|
||||||
void Room::mediaProduceVideo(JNIEnv* env, webrtc::MediaStreamInterface* mediaStream) {
|
void Room::mediaProduceVideo(JNIEnv* env, webrtc::MediaStreamInterface* mediaStream) {
|
||||||
if(!this->device->CanProduce("video")) {
|
if(!this->device->CanProduce("video")) {
|
||||||
|
LOG_I("不能生产视频媒体:%s", this->roomId.data());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO:配置读取
|
// TODO:配置读取同时测试效果
|
||||||
nlohmann::json codecOptions =
|
nlohmann::json codecOptions =
|
||||||
{
|
{
|
||||||
|
// x-google-start-bitrate
|
||||||
{ "videoGoogleStartBitrate", 400 },
|
{ "videoGoogleStartBitrate", 400 },
|
||||||
|
// x-google-min-bitrate
|
||||||
{ "videoGoogleMinBitrate", 800 },
|
{ "videoGoogleMinBitrate", 800 },
|
||||||
|
// x-google-max-bitrate
|
||||||
{ "videoGoogleMaxBitrate", 1600 }
|
{ "videoGoogleMaxBitrate", 1600 }
|
||||||
};
|
};
|
||||||
// 如果需要使用`Simulcast`打开下面配置
|
// 如果需要使用`Simulcast`打开下面配置
|
||||||
@@ -385,8 +514,8 @@ namespace acgist {
|
|||||||
jstring jRoomId, jobject jRouterCallback
|
jstring jRoomId, jobject jRouterCallback
|
||||||
) {
|
) {
|
||||||
jobject routerCallback = env->NewGlobalRef(jRouterCallback);
|
jobject routerCallback = env->NewGlobalRef(jRouterCallback);
|
||||||
const char* roomId = env->GetStringUTFChars(jRoomId, nullptr);
|
const char* roomId = env->GetStringUTFChars(jRoomId, nullptr);
|
||||||
Room* room = new Room(roomId, routerCallback);
|
Room* room = new Room(roomId, routerCallback);
|
||||||
env->DeleteLocalRef(jRoomId);
|
env->DeleteLocalRef(jRoomId);
|
||||||
env->ReleaseStringUTFChars(jRoomId, roomId);
|
env->ReleaseStringUTFChars(jRoomId, roomId);
|
||||||
return (jlong) room;
|
return (jlong) room;
|
||||||
@@ -424,7 +553,7 @@ namespace acgist {
|
|||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
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;
|
Room* room = (Room*) nativeRoomPointer;
|
||||||
const char* body = env->GetStringUTFChars(jBody, nullptr);
|
const char* body = env->GetStringUTFChars(jBody, nullptr);
|
||||||
room->createSendTransport(env, body);
|
room->createSendTransport(env, body);
|
||||||
env->DeleteLocalRef(jBody);
|
env->DeleteLocalRef(jBody);
|
||||||
@@ -433,7 +562,7 @@ namespace acgist {
|
|||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
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;
|
Room* room = (Room*) nativeRoomPointer;
|
||||||
const char* body = env->GetStringUTFChars(jBody, nullptr);
|
const char* body = env->GetStringUTFChars(jBody, nullptr);
|
||||||
room->createRecvTransport(env, body);
|
room->createRecvTransport(env, body);
|
||||||
env->DeleteLocalRef(jBody);
|
env->DeleteLocalRef(jBody);
|
||||||
@@ -454,7 +583,7 @@ namespace acgist {
|
|||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
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;
|
Room* room = (Room*) nativeRoomPointer;
|
||||||
const char* message = env->GetStringUTFChars(jMessage, nullptr);
|
const char* message = env->GetStringUTFChars(jMessage, nullptr);
|
||||||
room->mediaConsume(env, message);
|
room->mediaConsume(env, message);
|
||||||
env->DeleteLocalRef(jMessage);
|
env->DeleteLocalRef(jMessage);
|
||||||
@@ -463,7 +592,7 @@ namespace acgist {
|
|||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
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;
|
Room* room = (Room*) nativeRoomPointer;
|
||||||
const char* producerId = env->GetStringUTFChars(jProducerId, nullptr);
|
const char* producerId = env->GetStringUTFChars(jProducerId, nullptr);
|
||||||
room->mediaProducerPause(env, producerId);
|
room->mediaProducerPause(env, producerId);
|
||||||
env->DeleteLocalRef(jProducerId);
|
env->DeleteLocalRef(jProducerId);
|
||||||
@@ -472,7 +601,7 @@ namespace acgist {
|
|||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
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;
|
Room* room = (Room*) nativeRoomPointer;
|
||||||
const char* producerId = env->GetStringUTFChars(jProducerId, nullptr);
|
const char* producerId = env->GetStringUTFChars(jProducerId, nullptr);
|
||||||
room->mediaProducerResume(env, producerId);
|
room->mediaProducerResume(env, producerId);
|
||||||
env->DeleteLocalRef(jProducerId);
|
env->DeleteLocalRef(jProducerId);
|
||||||
@@ -481,7 +610,7 @@ namespace acgist {
|
|||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
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;
|
Room* room = (Room*) nativeRoomPointer;
|
||||||
const char* producerId = env->GetStringUTFChars(jProducerId, nullptr);
|
const char* producerId = env->GetStringUTFChars(jProducerId, nullptr);
|
||||||
room->mediaProducerClose(env, producerId);
|
room->mediaProducerClose(env, producerId);
|
||||||
env->DeleteLocalRef(jProducerId);
|
env->DeleteLocalRef(jProducerId);
|
||||||
@@ -490,7 +619,7 @@ namespace acgist {
|
|||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
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;
|
Room* room = (Room*) nativeRoomPointer;
|
||||||
const char* consumerId = env->GetStringUTFChars(jConsumerId, nullptr);
|
const char* consumerId = env->GetStringUTFChars(jConsumerId, nullptr);
|
||||||
room->mediaConsumerPause(env, consumerId);
|
room->mediaConsumerPause(env, consumerId);
|
||||||
env->DeleteLocalRef(jConsumerId);
|
env->DeleteLocalRef(jConsumerId);
|
||||||
@@ -499,7 +628,7 @@ namespace acgist {
|
|||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
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;
|
Room* room = (Room*) nativeRoomPointer;
|
||||||
const char* consumerId = env->GetStringUTFChars(jConsumerId, nullptr);
|
const char* consumerId = env->GetStringUTFChars(jConsumerId, nullptr);
|
||||||
room->mediaConsumerResume(env, consumerId);
|
room->mediaConsumerResume(env, consumerId);
|
||||||
env->DeleteLocalRef(jConsumerId);
|
env->DeleteLocalRef(jConsumerId);
|
||||||
@@ -508,7 +637,7 @@ namespace acgist {
|
|||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
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;
|
Room* room = (Room*) nativeRoomPointer;
|
||||||
const char* consumerId = env->GetStringUTFChars(jConsumerId, nullptr);
|
const char* consumerId = env->GetStringUTFChars(jConsumerId, nullptr);
|
||||||
room->mediaConsumerClose(env, consumerId);
|
room->mediaConsumerClose(env, consumerId);
|
||||||
env->DeleteLocalRef(jConsumerId);
|
env->DeleteLocalRef(jConsumerId);
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ import java.util.function.Consumer;
|
|||||||
* 视频会话
|
* 视频会话
|
||||||
* SDK + WebRTC实现视频会话
|
* SDK + WebRTC实现视频会话
|
||||||
*
|
*
|
||||||
|
* TODO:通过setRemoteDescription设置x-google-start-bitrate、x-google-min-bitrate、x-google-max-bitrate
|
||||||
|
*
|
||||||
* 注意:
|
* 注意:
|
||||||
* 2. offer/answer/candidate枚举大小
|
* 2. offer/answer/candidate枚举大小
|
||||||
* 1. candidate格式安卓和浏览器格式不同
|
* 1. candidate格式安卓和浏览器格式不同
|
||||||
|
|||||||
@@ -218,9 +218,10 @@ export default {
|
|||||||
.menus{width:100%;top:1rem;left:0;text-align:center;position:fixed;z-index:1;}
|
.menus{width:100%;top:1rem;left:0;text-align:center;position:fixed;z-index:1;}
|
||||||
.clients{width:100%;height:100%;top:0;left:0;position:fixed;}
|
.clients{width:100%;height:100%;top:0;left:0;position:fixed;}
|
||||||
.client{float:left;width:50vw;height:50vh;box-shadow:0 0 1px 0px rgba(0,0,0,0.4);}
|
.client{float:left;width:50vw;height:50vh;box-shadow:0 0 1px 0px rgba(0,0,0,0.4);}
|
||||||
.client .buttons{width:100%;bottom:2px;left:0;text-align:center;position:absolute;padding:0.8rem 0;background:rgba(0,0,0,0.4);}
|
|
||||||
.client .buttons:after{width:0;height:2px;bottom:0;left:0;position:absolute;background:#C00;content:"";transition: all 400ms linear;}
|
|
||||||
.client audio{display:none;}
|
.client audio{display:none;}
|
||||||
.client video{width:100%;height:100%;}
|
.client video{width:100%;height:100%;}
|
||||||
|
.client .mic{background:linear-gradient(to top, var(--el-color-primary) 10%, transparent 0%);}
|
||||||
.client .title{position:absolute;top:0;left:0;text-align:center;width:100%;}
|
.client .title{position:absolute;top:0;left:0;text-align:center;width:100%;}
|
||||||
</style>
|
.client .buttons{width:100%;bottom:0;left:0;text-align:center;position:absolute;padding:0.8rem 0;background:rgba(0,0,0,0.4);}
|
||||||
|
.client .buttons .el-button{margin:0 6px;}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
/**
|
/**
|
||||||
* 音频默认配置
|
* 音频默认配置
|
||||||
* TODO:MediaStreamTrack.applyConstraints()
|
* TODO:MediaStreamTrack.applyConstraints().then().catch();
|
||||||
|
* let setting = {
|
||||||
|
* autoGainControl: true,
|
||||||
|
* noiseSuppression: true
|
||||||
|
* }
|
||||||
|
await track.applyConstraints(Object.assign(track.getSettings(), setting));
|
||||||
* TODO:播放音量(audio标签配置)、采集音量
|
* TODO:播放音量(audio标签配置)、采集音量
|
||||||
* 支持属性:navigator.mediaDevices.getSupportedConstraints()
|
* 支持属性:navigator.mediaDevices.getSupportedConstraints()
|
||||||
* https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings
|
* https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
<audio ref="audio"></audio>
|
<audio ref="audio"></audio>
|
||||||
<video ref="video"></video>
|
<video ref="video"></video>
|
||||||
<p class="title">{{ client?.name || "" }}</p>
|
<p class="title">{{ client?.name || "" }}</p>
|
||||||
<div class="buttons" :style="{'--volume': client?.volume}">
|
<div class="buttons">
|
||||||
<el-button @click="taoyao.mediaProducerResume(audioProducer.id)" v-show="audioProducer && audioProducer.paused" type="primary" title="打开麦克风" :icon="Microphone" circle />
|
<el-button @click="taoyao.mediaProducerResume(audioProducer.id)" v-show="audioProducer && audioProducer.paused" type="danger" title="打开麦克风" :icon="Mute" circle />
|
||||||
<el-button @click="taoyao.mediaProducerPause(audioProducer.id)" v-show="audioProducer && !audioProducer.paused" type="danger" title="关闭麦克风" :icon="Mute" circle />
|
<el-button @click="taoyao.mediaProducerPause(audioProducer.id)" v-show="audioProducer && !audioProducer.paused" type="primary" title="关闭麦克风" :icon="Microphone" circle class="mic" :style="{'--volume': client?.volume}" />
|
||||||
<el-button @click="taoyao.mediaProducerResume(videoProducer.id)" v-show="videoProducer && videoProducer.paused" type="primary" title="打开摄像头" :icon="VideoPlay" circle />
|
<el-button @click="taoyao.mediaProducerResume(videoProducer.id)" v-show="videoProducer && videoProducer.paused" type="danger" title="打开摄像头" :icon="VideoPlay" circle />
|
||||||
<el-button @click="taoyao.mediaProducerPause(videoProducer.id)" v-show="videoProducer && !videoProducer.paused" type="danger" title="关闭摄像头" :icon="VideoPause" circle />
|
<el-button @click="taoyao.mediaProducerPause(videoProducer.id)" v-show="videoProducer && !videoProducer.paused" type="primary" title="关闭摄像头" :icon="VideoPause" circle />
|
||||||
<el-button @click="exchangeVideoSource" :icon="Refresh" circle title="交换媒体" />
|
<el-button @click="exchangeVideoSource" :icon="Refresh" circle title="交换媒体" />
|
||||||
<el-button :icon="Camera" circle title="拍照" />
|
<el-button :icon="Camera" circle title="拍照" />
|
||||||
<el-button :icon="VideoCamera" circle title="录像" />
|
<el-button :icon="VideoCamera" circle title="录像" />
|
||||||
@@ -107,5 +107,5 @@ export default {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.client .buttons:after{width:var(--volume);}
|
.client .mic{background:linear-gradient(to top, var(--el-color-primary) var(--volume), transparent 0%);}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
<!-- 远程终端 -->
|
<!-- 远程终端 -->
|
||||||
|
<!--
|
||||||
|
注意:当生产者关闭以后不能操作该生产者生产的消费者
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="client">
|
<div class="client">
|
||||||
<audio ref="audio"></audio>
|
<audio ref="audio"></audio>
|
||||||
<video ref="video"></video>
|
<video ref="video"></video>
|
||||||
<p class="title">{{ client?.name || "" }}</p>
|
<p class="title">{{ client?.name || "" }}</p>
|
||||||
<div class="buttons" :style="{'--volume': client?.volume}">
|
<div class="buttons">
|
||||||
<!-- TODO:本地状态+远程状态计算当前状态 -->
|
<el-button @click="taoyao.mediaConsumerResume(audioConsumer.id)" v-show="audioConsumer && audioConsumer.paused" type="danger" title="打开麦克风" :icon="Mute" circle />
|
||||||
<el-button @click="taoyao.mediaConsumerResume(audioConsumer.id)" v-show="audioConsumer && audioConsumer.paused" type="primary" title="打开麦克风" :icon="Microphone" circle />
|
<el-button @click="taoyao.mediaConsumerPause(audioConsumer.id)" v-show="audioConsumer && !audioConsumer.paused" type="primary" title="关闭麦克风" :icon="Microphone" circle class="mic" :style="{'--volume': client?.volume}" />
|
||||||
<el-button @click="taoyao.mediaConsumerPause(audioConsumer.id)" v-show="audioConsumer && !audioConsumer.paused" type="danger" title="关闭麦克风" :icon="Mute" circle />
|
<el-button @click="taoyao.mediaConsumerResume(videoConsumer.id)" v-show="videoConsumer && videoConsumer.paused" type="danger" title="打开摄像头" :icon="VideoPlay" circle />
|
||||||
<el-button @click="taoyao.mediaConsumerResume(videoConsumer.id)" v-show="videoConsumer && videoConsumer.paused" type="primary" title="打开摄像头" :icon="VideoPlay" circle />
|
<el-button @click="taoyao.mediaConsumerPause(videoConsumer.id)" v-show="videoConsumer && !videoConsumer.paused" type="primary" title="关闭摄像头" :icon="VideoPause" circle />
|
||||||
<el-button @click="taoyao.mediaConsumerPause(videoConsumer.id)" v-show="videoConsumer && !videoConsumer.paused" type="danger" title="关闭摄像头" :icon="VideoPause" circle />
|
|
||||||
<el-button @click="taoyao.controlPhotograph(client.clientId)" :icon="Camera" circle title="拍照" />
|
<el-button @click="taoyao.controlPhotograph(client.clientId)" :icon="Camera" circle title="拍照" />
|
||||||
<el-button @click="taoyao.controlRecord(client.clientId, (record = !record))" :icon="VideoCamera" circle title="录像" :type="record ? 'danger' : ''" />
|
<el-button @click="taoyao.controlRecord(client.clientId, (record = !record))" :icon="VideoCamera" circle title="录像" :type="record ? 'danger' : ''" />
|
||||||
<el-button @click="taoyao.mediaConsumerStatus()" :icon="InfoFilled" circle title="媒体信息" />
|
<el-button @click="taoyao.mediaConsumerStatus()" :icon="InfoFilled" circle title="媒体信息" />
|
||||||
@@ -112,5 +114,5 @@ export default {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.client .buttons:after{width:var(--volume);}
|
.client .mic{background:linear-gradient(to top, var(--el-color-primary) var(--volume), transparent 0%);}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
<video ref="video"></video>
|
<video ref="video"></video>
|
||||||
<p class="title">{{ client?.name || "" }}</p>
|
<p class="title">{{ client?.name || "" }}</p>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<el-button @click="taoyao.sessionResume(client.id, 'audio')" v-show="audioStream && !client.remoteAudioEnabled" type="primary" title="打开麦克风" :icon="Microphone" circle />
|
<el-button @click="taoyao.sessionResume(client.id, 'audio')" v-show="audioStream && !client.remoteAudioEnabled" type="danger" title="打开麦克风" :icon="Mute" circle />
|
||||||
<el-button @click="taoyao.sessionPause(client.id, 'audio')" v-show="audioStream && client.remoteAudioEnabled" type="danger" title="关闭麦克风" :icon="Mute" circle />
|
<el-button @click="taoyao.sessionPause(client.id, 'audio')" v-show="audioStream && client.remoteAudioEnabled" type="primary" title="关闭麦克风" :icon="Microphone" circle class="mic" :style="{'--volume': client?.volume}" />
|
||||||
<el-button @click="taoyao.sessionResume(client.id, 'video')" v-show="videoStream && !client.remoteVideoEnabled" type="primary" title="打开摄像头" :icon="VideoPlay" circle />
|
<el-button @click="taoyao.sessionResume(client.id, 'video')" v-show="videoStream && !client.remoteVideoEnabled" type="danger" title="打开摄像头" :icon="VideoPlay" circle />
|
||||||
<el-button @click="taoyao.sessionPause(client.id, 'video')" v-show="videoStream && client.remoteVideoEnabled" type="danger" title="关闭摄像头" :icon="VideoPause" circle />
|
<el-button @click="taoyao.sessionPause(client.id, 'video')" v-show="videoStream && client.remoteVideoEnabled" type="primary" title="关闭摄像头" :icon="VideoPause" circle />
|
||||||
<el-button @click="taoyao.controlPhotograph(client.clientId)" :icon="Camera" circle title="拍照" />
|
<el-button @click="taoyao.controlPhotograph(client.clientId)" :icon="Camera" circle title="拍照" />
|
||||||
<el-button @click="taoyao.controlRecord(client.clientId, (record = !record))" :icon="VideoCamera" circle title="录像" :type="record ? 'danger' : ''" />
|
<el-button @click="taoyao.controlRecord(client.clientId, (record = !record))" :icon="VideoCamera" circle title="录像" :type="record ? 'danger' : ''" />
|
||||||
<el-popover placement="top" :width="240" trigger="hover">
|
<el-popover placement="top" :width="240" trigger="hover">
|
||||||
@@ -104,3 +104,6 @@ export default {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.client .mic{background:linear-gradient(to top, var(--el-color-primary) var(--volume), transparent 0%);}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -243,6 +243,8 @@ class Session {
|
|||||||
id;
|
id;
|
||||||
// 远程终端名称
|
// 远程终端名称
|
||||||
name;
|
name;
|
||||||
|
// 音量
|
||||||
|
volume = 100;
|
||||||
// 是否关闭
|
// 是否关闭
|
||||||
closed;
|
closed;
|
||||||
// 远程终端ID
|
// 远程终端ID
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 休眠一秒:等待后台任务调度
|
||||||
|
sleep 1
|
||||||
|
|
||||||
# 等待任务
|
# 等待任务
|
||||||
startTime=$(date +%s)
|
startTime=$(date +%s)
|
||||||
processId=$(ps -aux | grep "${project.artifactId}" | grep java | awk '{print $2}')
|
processId=$(ps -aux | grep "${project.artifactId}" | grep java | awk '{print $2}')
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ import lombok.Setter;
|
|||||||
* 视频编码 = 压缩
|
* 视频编码 = 压缩
|
||||||
* 8 = 颜色位数
|
* 8 = 颜色位数
|
||||||
* 3 / 2 = YUV | RGB
|
* 3 / 2 = YUV | RGB
|
||||||
|
* 码率(比特率):单位(kbps | kbit/s | kb/s)
|
||||||
|
* 码率 = 文件字节大小 * 8 / 秒数 / 1000
|
||||||
|
* 1Byte = 8bit
|
||||||
*
|
*
|
||||||
* @author acgist
|
* @author acgist
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user