diff --git a/privmx-endpoint/src/main/cpp/model_native_initializers.cpp b/privmx-endpoint/src/main/cpp/model_native_initializers.cpp index 2577819f..2cf6c769 100644 --- a/privmx-endpoint/src/main/cpp/model_native_initializers.cpp +++ b/privmx-endpoint/src/main/cpp/model_native_initializers.cpp @@ -1394,5 +1394,130 @@ namespace privmx { ); } + //Stream + jobject stream2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::Stream stream_c + ) { + jclass itemCls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/Stream"); + + jmethodID initItemMID = ctx->GetMethodID( + itemCls, + "", + "(" + "Ljava/lang/Long;" // streamId + "Ljava/lang/String;" // userId + ")V" + ); + + return ctx->NewObject( + itemCls, + initItemMID, + ctx.long2jLong(stream_c.streamId), + ctx->NewStringUTF(stream_c.userId.c_str()) + ); + } + + jobject deviceType2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::DeviceType deviceType_c + ) { + jclass itemCls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/streams/DeviceType"); + + jmethodID valuesMID = ctx->GetStaticMethodID(itemCls, "values", + "()[Lcom/simplito/java/privmx_endpoint/model/streams/DeviceType;"); + + jobjectArray enumValues = (jobjectArray) ctx->CallStaticObjectMethod(itemCls, + valuesMID); + + return (jobject) ctx->GetObjectArrayElement(enumValues, (int) deviceType_c); + } + + + jobject mediaDevice2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::MediaDevice mediaDevice_c + ) { + jclass itemCls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/streams/MediaDevice"); + + jmethodID initItemMID = ctx->GetMethodID( + itemCls, + "", + "(" + "Ljava/lang/String;" // name + "Ljava/lang/String;" // id + "Lcom/simplito/java/privmx_endpoint/model/streams/DeviceType;" // type + ")V" + ); + + return ctx->NewObject( + itemCls, + initItemMID, + ctx->NewStringUTF(mediaDevice_c.name.c_str()), + ctx->NewStringUTF(mediaDevice_c.id.c_str()), + deviceType2Java(ctx, mediaDevice_c.type) + + ); + } + + jobject streamHandle2Java( + JniContextUtils &ctx, + privmx::endpoint::stream::StreamHandle streamHandle_c + ) { + jclass itemCls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/streams/StreamHandle"); + + jmethodID initItemMID = ctx->GetMethodID( + itemCls, + "", + "(" + "Ljava/lang/Long;" // value + ")V" + ); + + return ctx->NewObject( + itemCls, + initItemMID, + ctx.long2jLong(streamHandle_c) + ); + } + + jobject remoteStreamId2Java(JniContextUtils &ctx, privmx::endpoint::stream::RemoteStreamId remoteStreamId_c){ + jclass itemCls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/streams/RemoteStreamId"); + + jmethodID initItemMID = ctx->GetMethodID( + itemCls, + "", + "(" + "Ljava/lang/Long;" // value + ")V" + ); + + return ctx->NewObject( + itemCls, + initItemMID, + ctx.long2jLong(remoteStreamId_c) + ); + } + + jobject frame2Java(JniContextUtils &ctx, privmx::endpoint::stream::Frame &frame_c) { + jclass itemCls = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/streams/Frame"); + + jmethodID initItemMID = ctx->GetMethodID( + itemCls, + "", + "()V" + ); + + return ctx->NewObject( + itemCls, + initItemMID + ); + } } // wrapper } // privmx \ No newline at end of file diff --git a/privmx-endpoint/src/main/cpp/model_native_initializers.h b/privmx-endpoint/src/main/cpp/model_native_initializers.h index f83c7959..bd73a07e 100644 --- a/privmx-endpoint/src/main/cpp/model_native_initializers.h +++ b/privmx-endpoint/src/main/cpp/model_native_initializers.h @@ -34,6 +34,8 @@ #include "privmx/endpoint/crypto/ExtKey.hpp" #include "privmx/endpoint/kvdb/KvdbApi.hpp" #include "privmx/endpoint/kvdb/Types.hpp" +#include "privmx/endpoint/stream/Types.hpp" +#include "privmx/endpoint/stream/webrtc/Types.hpp" namespace privmx { namespace wrapper { @@ -161,6 +163,18 @@ namespace privmx { jobject kvdbEntry2Java(JniContextUtils &ctx, privmx::endpoint::kvdb::KvdbEntry entry_c); + //Stream + jobject stream2Java(JniContextUtils &ctx, privmx::endpoint::stream::Stream stream_c); + + jobject deviceType2Java(JniContextUtils &ctx,privmx::endpoint::stream::DeviceType deviceType_c); + + jobject mediaDevice2Java(JniContextUtils &ctx, privmx::endpoint::stream::MediaDevice mediaDevice_c); + + jobject streamHandle2Java(JniContextUtils &ctx, privmx::endpoint::stream::StreamHandle streamHandle_c); + + jobject remoteStreamId2Java(JniContextUtils &ctx, privmx::endpoint::stream::RemoteStreamId remoteStreamId_c); + + jobject frame2Java(JniContextUtils &ctx, privmx::endpoint::stream::Frame &frame_c); } // wrapper } // privmx diff --git a/privmx-endpoint/src/main/cpp/modules/StreamApi.cpp b/privmx-endpoint/src/main/cpp/modules/StreamApi.cpp index 6cc1fbce..1851b1c6 100644 --- a/privmx-endpoint/src/main/cpp/modules/StreamApi.cpp +++ b/privmx-endpoint/src/main/cpp/modules/StreamApi.cpp @@ -56,4 +56,297 @@ Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApi_deinit( e.what() ); } +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApi_listStreams( + JNIEnv *env, + jobject thiz, + jstring stream_room_id +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_room_id, "Stream Room ID")) { + return nullptr; + } + + jobject result; + ctx.callResultEndpointApi( + &result, + [&ctx, &thiz, &stream_room_id]() { + std::vector streams_c = getStreamApi( + ctx, thiz)->listStreams( + ctx.jString2string(stream_room_id) + ); + + return vectorTojArray(ctx, streams_c, privmx::wrapper::stream2Java); + } + ); + + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; +} +extern "C" +JNIEXPORT jobject JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApi_createStream( + JNIEnv *env, + jobject thiz, + jstring stream_room_id +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_room_id, "Stream Room ID")) { + return nullptr; + } + jobject result; + ctx.callResultEndpointApi( + &result, + [&ctx, &thiz, &stream_room_id]() { + auto stream_c( + getStreamApi(ctx, thiz)->createStream( + ctx.jString2string(stream_room_id) + ) + ); + return privmx::wrapper::streamHandle2Java(ctx, stream_c); + } + ); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApi_getMediaDevices( + JNIEnv *env, + jobject thiz +) { + JniContextUtils ctx(env); + jobject result; + ctx.callResultEndpointApi( + &result, + [&ctx, &thiz]() { + auto media_devices_c( + getStreamApi(ctx, thiz)->getMediaDevices() + ); + return vectorTojArray(ctx, media_devices_c, privmx::wrapper::mediaDevice2Java); + } + ); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; +} +extern "C" +JNIEXPORT void JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApi_addTrack( + JNIEnv *env, jobject thiz, + jobject stream_handle, + jobject track +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_handle, "Stream Handle") || + ctx.nullCheck(track, "Track")) { + return; + } + ctx.callVoidEndpointApi([&ctx, &thiz, &stream_handle, &track]() { + getStreamApi(ctx, thiz)->addTrack( + parseStreamHandle(ctx, stream_handle), + parseMediaDevice(ctx, track) + ); + }); +} +extern "C" +JNIEXPORT void JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApi_removeTrack( + JNIEnv *env, + jobject thiz, + jobject stream_handle, + jobject track +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_handle, "Stream Handle") || + ctx.nullCheck(track, "Track")) { + return; + } + ctx.callVoidEndpointApi([&ctx, &thiz, &stream_handle, &track]() { + getStreamApi(ctx, thiz)->removeTrack( + parseStreamHandle(ctx, stream_handle), + parseMediaDevice(ctx, track) + ); + }); +} + +extern "C" +JNIEXPORT jobject JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApi_publishStream( + JNIEnv *env, + jobject thiz, + jobject stream_handle +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_handle, "Stream Handle")) { + return nullptr; + } + + jobject result; + ctx.callResultEndpointApi( + &result, + [&ctx, &env, &thiz, &stream_handle]() { + auto id = + getStreamApi(ctx, thiz)->publishStream( + parseStreamHandle(ctx, stream_handle)); + return privmx::wrapper::remoteStreamId2Java(ctx, id); + } + ); + if (ctx->ExceptionCheck()) { + return nullptr; + } + return result; +} + +extern "C" +JNIEXPORT void JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApi_unpublishStream( + JNIEnv *env, + jobject thiz, + jobject stream_handle +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_handle, "Stream Handle")){ + return; + } + + ctx.callVoidEndpointApi([&ctx, &thiz, &stream_handle]() { + getStreamApi(ctx, thiz)->unpublishStream( + parseStreamHandle(ctx, stream_handle) + ); + }); +} + +extern "C" +JNIEXPORT void JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApi_subscribeToRemoteStreams( + JNIEnv *env, + jobject thiz, + jstring stream_room_id, + jobject subscriptions, + jobject options +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_room_id, "Stream Room ID") || + ctx.nullCheck(options, "Options") || + ctx.nullCheck(subscriptions, "Subscriptions List")) { + return; + } + + ctx.callVoidEndpointApi([&ctx, &thiz, &stream_room_id, &subscriptions, &options, &env]() { + std::vector subscriptions_c = + jArrayToVector( + ctx, + ctx.jObject2jArray( + subscriptions), + parseStreamSubscription + ); + getStreamApi(ctx, thiz)->subscribeToRemoteStreams( + ctx.jString2string(stream_room_id), + subscriptions_c, + parseStreamSettings(env, options) + ); + }); +} + +extern "C" +JNIEXPORT void JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApi_modifyRemoteStreamsSubscriptions( + JNIEnv *env, + jobject thiz, + jstring stream_room_id, + jobject subscriptions_to_add, + jobject subscriptions_to_remove, + jobject options +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_room_id, "Stream Room ID") || + ctx.nullCheck(options, "Options") || + ctx.nullCheck(subscriptions_to_add, "Subscriptions To Add List") || + ctx.nullCheck(subscriptions_to_remove, "Subscriptions To Remove List")) { + return; + } + + ctx.callVoidEndpointApi( + [&ctx, &thiz, &stream_room_id, &subscriptions_to_add, &subscriptions_to_remove, &options, &env]() { + std::vector subscriptions_to_add_c = + jArrayToVector( + ctx, + ctx.jObject2jArray( + subscriptions_to_add), + parseStreamSubscription + ); + std::vector subscriptions_to_remove_c = + jArrayToVector( + ctx, + ctx.jObject2jArray( + subscriptions_to_remove), + parseStreamSubscription + ); + getStreamApi(ctx, thiz)->modifyRemoteStreamsSubscriptions( + ctx.jString2string(stream_room_id), + subscriptions_to_add_c, + subscriptions_to_remove_c, + parseStreamSettings(env, options) + ); + }); +} + +extern "C" +JNIEXPORT void JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApi_unsubscribeFromRemoteStreams( + JNIEnv *env, + jobject thiz, + jstring stream_room_id, + jobject subscriptions_to_remove +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_room_id, "Stream Room ID") || + ctx.nullCheck(subscriptions_to_remove, "Subscriptions To Remove List")) { + return; + } + + ctx.callVoidEndpointApi([&ctx, &thiz, &stream_room_id, &subscriptions_to_remove]() { + std::vector subscriptions_to_remove_c = + jArrayToVector( + ctx, + ctx.jObject2jArray( + subscriptions_to_remove), + parseStreamSubscription + ); + getStreamApi(ctx, thiz)->unsubscribeFromRemoteStreams( + ctx.jString2string(stream_room_id), + subscriptions_to_remove_c + ); + }); +} + +extern "C" +JNIEXPORT void JNICALL +Java_com_simplito_java_privmx_1endpoint_modules_stream_StreamApi_dropBrokenFrames( + JNIEnv *env, + jobject thiz, + jstring stream_room_id, + jboolean enable +) { + JniContextUtils ctx(env); + if (ctx.nullCheck(stream_room_id, "Stream Room ID")) { + return; + } + + ctx.callVoidEndpointApi([&ctx, &thiz, &stream_room_id, &enable]() { + getStreamApi(ctx, thiz)->dropBrokenFrames( + ctx.jString2string(stream_room_id), + enable == JNI_TRUE + ); + }); } \ No newline at end of file diff --git a/privmx-endpoint/src/main/cpp/modules/StreamApi.h b/privmx-endpoint/src/main/cpp/modules/StreamApi.h index 1fccf8e1..d388fdb6 100644 --- a/privmx-endpoint/src/main/cpp/modules/StreamApi.h +++ b/privmx-endpoint/src/main/cpp/modules/StreamApi.h @@ -1,6 +1,7 @@ #include #include #include "../utils.hpp" +#include "../model_native_initializers.h" #include "Connection.h" #include "EventApi.h" diff --git a/privmx-endpoint/src/main/cpp/parser.cpp b/privmx-endpoint/src/main/cpp/parser.cpp index 72bc667a..d3fd541f 100644 --- a/privmx-endpoint/src/main/cpp/parser.cpp +++ b/privmx-endpoint/src/main/cpp/parser.cpp @@ -573,6 +573,97 @@ parsePagingQuery(JniContextUtils &ctx, jobject pagingQuery) { return result; } +// streams +privmx::endpoint::stream::DeviceType parseDeviceType(JniContextUtils &ctx, jobject type) { + jclass itemClass = ctx->FindClass( + "com/simplito/java/privmx_endpoint/model/streams/DeviceType)"); + jmethodID ordinalMethod = ctx->GetMethodID(itemClass, "ordinal", "()I"); + jint ordinalMID = ctx->CallIntMethod(type, ordinalMethod); + + privmx::endpoint::stream::DeviceType type_c = static_cast(ordinalMID); + + return type_c; +} + +privmx::endpoint::stream::MediaDevice parseMediaDevice(JniContextUtils &ctx, jobject mediaDevice) { + auto result = privmx::endpoint::stream::MediaDevice(); + + jclass mediaDeviceCls = ctx->GetObjectClass(mediaDevice); + jfieldID name = ctx->GetFieldID(mediaDeviceCls, "name", "Ljava/lang/String;"); + jfieldID id = ctx->GetFieldID(mediaDeviceCls, "id", "Ljava/lang/String;"); + jfieldID type = ctx->GetFieldID(mediaDeviceCls, "type", + "Lcom/simplito/java/privmx_endpoint/model/streams/DeviceType;"); + + result.name = ctx.jString2string( + (jstring) ctx->GetObjectField(mediaDevice, name)); + result.id = ctx.jString2string( + (jstring) ctx->GetObjectField(mediaDevice, id)); + result.type = parseDeviceType(ctx, ctx->GetObjectField(mediaDevice, type)); + + return result; +} + +privmx::endpoint::stream::StreamHandle parseStreamHandle( + JniContextUtils &ctx, + jobject streamHandle +) { + jclass streamHandleCls = ctx->GetObjectClass(streamHandle); + jfieldID valueFID = ctx->GetFieldID(streamHandleCls, "value", "Ljava/lang/Long;"); + + return jobject2long(ctx, ctx->GetObjectField(streamHandle, valueFID)); +} + +privmx::endpoint::stream::Settings parseSettings(JniContextUtils &ctx, jobject settings){ + auto result = privmx::endpoint::stream::Settings(); + return result; +} + +privmx::endpoint::stream::StreamSettings parseStreamSettings(JNIEnv *env,jobject streamSettings){ + privmx::endpoint::stream::StreamSettings result; + JniContextUtils ctx(env); + jclass cls = ctx->GetObjectClass(streamSettings); + StreamSettingsJNI streamSettingsJni (env, streamSettings); + + jfieldID settingsFID = env->GetFieldID( + env->GetObjectClass(streamSettings), + "settings", + "Lcom/simplito/java/privmx_endpoint/model/streams/Settings;" + ); + + jobject jsettings = ctx->GetObjectField(streamSettings, settingsFID); + + result.settings = parseSettings(ctx, jsettings); + result.OnFrame = streamSettingsJni.OnFrame; + result.OnVideo = streamSettingsJni.OnVideo; + result.OnVideoRemove = streamSettingsJni.OnVideoRemove; + + return result; +} + +privmx::endpoint::stream::StreamSubscription parseStreamSubscription(JniContextUtils &ctx, jobject streamSubscription){ + privmx::endpoint::stream::StreamSubscription result; + jclass cls = ctx->GetObjectClass(streamSubscription); + jfieldID streamIdFID = ctx->GetFieldID( + ctx->GetObjectClass(streamSubscription), + "streamId", + "J" + ); + + jfieldID trackIdFID = ctx->GetFieldID( + ctx->GetObjectClass(streamSubscription), + "streamTrackId", + "Ljava/lang/String;" + ); + + jobject streamId = ctx->GetObjectField(streamSubscription, streamIdFID); + jobject streamTrackId = ctx->GetObjectField(streamSubscription, trackIdFID); + + result.streamId = jobject2long(ctx, streamId); + if(streamTrackId != nullptr) result.streamTrackId = jobject2string(ctx, streamTrackId); + + return result; +} + // java -> c++ template std::vector jArrayToVector( diff --git a/privmx-endpoint/src/main/cpp/parser.h b/privmx-endpoint/src/main/cpp/parser.h index b8a435e1..ffc68d38 100644 --- a/privmx-endpoint/src/main/cpp/parser.h +++ b/privmx-endpoint/src/main/cpp/parser.h @@ -13,7 +13,7 @@ #define PRIVMX_POCKET_LIB_PARSER_H #include "utils.hpp" - +#include "modules/StreamSettingsJNI.h" #include #include "model_native_initializers.h" @@ -37,6 +37,19 @@ jobject parseEvent(JniContextUtils &ctx, std::shared_ptr c++ template std::vector jArrayToVector(JniContextUtils &ctx, jobjectArray jArray, diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/DeviceType.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/DeviceType.java new file mode 100644 index 00000000..9167e570 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/DeviceType.java @@ -0,0 +1,7 @@ +package com.simplito.java.privmx_endpoint.model.streams; + +public enum DeviceType { + Audio, + Video, + Desktop +} \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/Frame.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/Frame.java new file mode 100644 index 00000000..e8dc75d5 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/Frame.java @@ -0,0 +1,8 @@ +package com.simplito.java.privmx_endpoint.model.streams; + +public abstract class Frame { + public Frame() {} + public int ConvertToRGBA(byte dst_argb, int dst_stride_argb, int dest_width, int dest_height){ + return 0; + }; +} \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/MediaDevice.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/MediaDevice.java new file mode 100644 index 00000000..ee5fc0d4 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/MediaDevice.java @@ -0,0 +1,13 @@ +package com.simplito.java.privmx_endpoint.model.streams; + +public class MediaDevice { + public String name; + public String id; + public DeviceType type; + + public MediaDevice(String name, String id, DeviceType type) { + this.name = name; + this.id = id; + this.type = type; + } +} \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/OnFrameCallback.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/OnFrameCallback.java new file mode 100644 index 00000000..65f8ba75 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/OnFrameCallback.java @@ -0,0 +1,6 @@ +package com.simplito.java.privmx_endpoint.model.streams; + +@FunctionalInterface +public interface OnFrameCallback { + void run(long width, long height, Frame frame, String id); +} \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/RemoteStreamId.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/RemoteStreamId.java new file mode 100644 index 00000000..a1a6e876 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/RemoteStreamId.java @@ -0,0 +1,9 @@ +package com.simplito.java.privmx_endpoint.model.streams; + +public class RemoteStreamId { + public final Long value; + + public RemoteStreamId(Long value) { + this.value = value; + } +} \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/Settings.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/Settings.java new file mode 100644 index 00000000..05f7bf10 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/Settings.java @@ -0,0 +1,6 @@ +package com.simplito.java.privmx_endpoint.model.streams; + +public class Settings { + public Settings() { + } +} \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/Stream.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/Stream.java new file mode 100644 index 00000000..1e579369 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/Stream.java @@ -0,0 +1,11 @@ +package com.simplito.java.privmx_endpoint.model.streams; + +public class Stream { + public Long streamId; + public String userId; + + public Stream(Long streamId, String userId) { + this.streamId = streamId; + this.userId = userId; + } +} diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/StreamHandle.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/StreamHandle.java new file mode 100644 index 00000000..4f348efe --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/StreamHandle.java @@ -0,0 +1,9 @@ +package com.simplito.java.privmx_endpoint.model.streams; + +public class StreamHandle { + public final Long value; + + public StreamHandle(Long value) { + this.value = value; + } +} \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/StreamSettings.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/StreamSettings.java new file mode 100644 index 00000000..eca53e49 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/StreamSettings.java @@ -0,0 +1,37 @@ +package com.simplito.java.privmx_endpoint.model.streams; + +import java.util.function.Consumer; + +public class StreamSettings { + public Settings settings; + public boolean dropCorruptedFrames = true; + public OnFrameCallback OnFrame = null; + public Consumer OnVideo = null; + public Consumer OnVideoRemove = null; + + public StreamSettings(Settings settings, boolean dropCorruptedFrames, OnFrameCallback onFrame, Consumer onVideo, Consumer onVideoRemove) { + this.settings = settings; + this.dropCorruptedFrames = dropCorruptedFrames; + OnFrame = onFrame; + OnVideo = onVideo; + OnVideoRemove = onVideoRemove; + } + + public StreamSettings(Settings settings, boolean dropCorruptedFrames, OnFrameCallback onFrame, Consumer onVideo) { + this(settings, dropCorruptedFrames, onFrame, onVideo, null); + } + + public StreamSettings(Settings settings, OnFrameCallback onFrame, boolean dropCorruptedFrames) { + this(settings, dropCorruptedFrames, onFrame, null, null); + + } + + public StreamSettings(Settings settings, boolean dropCorruptedFrames) { + this(settings, dropCorruptedFrames, null, null, null); + + } + + public StreamSettings(Settings settings) { + this(settings, true, null, null, null); + } +} \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/StreamSubscription.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/StreamSubscription.java new file mode 100644 index 00000000..9a4b9197 --- /dev/null +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/model/streams/StreamSubscription.java @@ -0,0 +1,15 @@ +package com.simplito.java.privmx_endpoint.model.streams; + +public class StreamSubscription { + public long streamId; + public String streamTrackId; + + public StreamSubscription(long streamId, String streamTrackId) { + this.streamId = streamId; + this.streamTrackId = streamTrackId; + } + + public StreamSubscription(long streamId) { + this.streamId = streamId; + } +} \ No newline at end of file diff --git a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApi.java b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApi.java index 6f7b512f..4dee82c8 100644 --- a/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApi.java +++ b/privmx-endpoint/src/main/java/com/simplito/java/privmx_endpoint/modules/stream/StreamApi.java @@ -1,15 +1,23 @@ package com.simplito.java.privmx_endpoint.modules.stream; import com.simplito.java.privmx_endpoint.LibLoader; +import com.simplito.java.privmx_endpoint.model.streams.MediaDevice; +import com.simplito.java.privmx_endpoint.model.streams.RemoteStreamId; +import com.simplito.java.privmx_endpoint.model.streams.Stream; +import com.simplito.java.privmx_endpoint.model.streams.StreamHandle; +import com.simplito.java.privmx_endpoint.model.streams.StreamSettings; +import com.simplito.java.privmx_endpoint.model.streams.StreamSubscription; import com.simplito.java.privmx_endpoint.modules.core.Connection; import com.simplito.java.privmx_endpoint.modules.event.EventApi; +import java.util.List; import java.util.Objects; public class StreamApi implements AutoCloseable { static { LibLoader.loadPrivmxLibraries(); } + @SuppressWarnings("FieldCanBeLocal") private final Long api; @@ -23,6 +31,28 @@ public StreamApi(Connection connection, EventApi eventApi) throws IllegalStateEx this.api = init(connection, eventApi); } + public native List listStreams(String streamRoomId); + + public native StreamHandle createStream(String streamRoomId); + + public native List getMediaDevices(); + + public native void addTrack(StreamHandle streamHandle, MediaDevice track); + + public native void removeTrack(StreamHandle streamHandle, MediaDevice track); + + public native RemoteStreamId publishStream(StreamHandle streamHandle); + + public native void unpublishStream(StreamHandle streamHandle); + + public native void subscribeToRemoteStreams(String streamRoomId, List subscriptions, StreamSettings options); + + public native void modifyRemoteStreamsSubscriptions(String streamRoomId, List subscriptionsToAdd, List subscriptionsToRemove, StreamSettings options); + + public native void unsubscribeFromRemoteStreams(String streamRoomId, List subscriptionsToRemove); + + public native void dropBrokenFrames(String streamRoomId, boolean enable); + @Override public void close() throws Exception { deinit();