Skip to content

Commit

Permalink
Added SIPJS api (#31)
Browse files Browse the repository at this point in the history
* Added SIPJS api

* Added missing file

* removed unavailable dead import

* Fixed wrong javadoc
  • Loading branch information
FlorianKirmaier authored Jan 8, 2024
1 parent 0d48433 commit f85d8e3
Show file tree
Hide file tree
Showing 25 changed files with 22,585 additions and 5 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -488,4 +488,6 @@ dependencies {
./gradlew jpro-media:example:jproRun -Psample=media-recorder-and-player
./gradlew jpro-routing:example:jproRun -Psample=colors
./gradlew jpro-routing:example:jproRun -Psample=test
./gradlew jpro-webrtc:example:jproRun
./gradlew jpro-sipjs:example:jproRun
```
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
JPRO_PLATFORM_VERSION = 0.2.11-SNAPSHOT

JPRO_VERSION = 2023.3.3
JPRO_VERSION = 2023.3.4-SNAPSHOT
JAVAFX_VERSION = 17.0.9
SIMPLEFX_VERSION = 3.2.28
JMEMORYBUDDY_VERSION = 0.5.1
Expand Down
5 changes: 5 additions & 0 deletions jpro-sipjs/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dependencies {
implementation "com.sandec.jpro:jpro-webapi:$JPRO_VERSION"
api project(':jpro-webrtc') // mainly to avoid duplicated code
api "org.json:json:$JSON_VERSION"
}
22 changes: 22 additions & 0 deletions jpro-sipjs/example/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
plugins {
id 'org.openjfx.javafxplugin'
id 'jpro-gradle-plugin'
}

mainClassName = "one.jpro.platform.sipjs.example.SIPJSApp"

application {
mainClass = "$mainClassName"
mainModule = moduleName
}

dependencies {
implementation project(':jpro-sipjs')
implementation project(':jpro-routing:core')
implementation project(':jpro-routing:dev')
}

javafx {
version = "$JAVAFX_VERSION"
modules = ['javafx.graphics', 'javafx.controls', 'javafx.swing', 'javafx.fxml', 'javafx.media', 'javafx.web']
}
11 changes: 11 additions & 0 deletions jpro-sipjs/example/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module one.jpro.platform.sipjs.example {
requires one.jpro.platform.sipjs;
requires javafx.controls;
requires jpro.webapi;
requires org.json;
requires one.jpro.platform.routing.core;
requires one.jpro.platform.webrtc;
requires one.jpro.platform.routing.dev;

exports one.jpro.platform.sipjs.example;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package one.jpro.platform.sipjs.example;

import one.jpro.platform.routing.Response;
import one.jpro.platform.routing.Route;
import one.jpro.platform.routing.RouteApp;
import one.jpro.platform.routing.dev.DevFilter;
import one.jpro.platform.sipjs.example.page.AliceAndBobPage;
import one.jpro.platform.sipjs.example.page.EchoPage;
import one.jpro.platform.sipjs.example.page.SelectPage;

public class SIPJSApp extends RouteApp {

@Override
public Route createRoute() {

getScene().getStylesheets().add(getClass().getResource("sipjsapp.css").toString());

return Route.empty()
.and(Route.get("/", r -> Response.node(new SelectPage())))
.and(Route.get("/echo", r -> Response.node(new EchoPage())))
.and(Route.get("/aliceAndBob", r -> Response.node(new AliceAndBobPage())))
.filter(DevFilter.create())
.and(Route.empty());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package one.jpro.platform.sipjs.example.page;

import com.jpro.webapi.WebAPI;
import javafx.application.Platform;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import one.jpro.platform.sipjs.api.UserAgent;
import one.jpro.platform.sipjs.api.options.InvitationAcceptOptions;
import one.jpro.platform.sipjs.api.options.InviterOptions;
import one.jpro.platform.sipjs.api.options.UserAgentOptions;
import one.jpro.platform.sipjs.api.session.Session;
import one.jpro.platform.webrtc.VideoFrame;

public class AliceAndBobPage extends VBox {


private String server = "wss://edge.sip.onsip.com";
String sipAlice = "sip:[email protected]";
String sipBob = "sip:[email protected]";

public AliceAndBobPage() {
// Add title
var title = new Label("Alice and Bob");
title.getStyleClass().add("title");
getChildren().add(title);
WebAPI.getWebAPI(this, webapi -> {
setup(webapi);
});
getStyleClass().add("jpro-sipjs-example-page");
}

public void setup(WebAPI webapi) {
var user1 = createUser(webapi, sipAlice, "Alice", sipBob);
var user2 = createUser(webapi, sipBob, "Bob", null);

var hbox = new HBox(user1, user2);
hbox.getStyleClass().add("alice-and-bob-hbox");

getChildren().addAll(hbox);
}


public Node createUser(WebAPI webapi, String sip, String displayName, String target) {
var options = new UserAgentOptions();
var container = new VBox();
container.getStyleClass().add("user-container");
container.getChildren().add(new Label(displayName+ ":"));
options.addServer(server);
options.addUri(sip);
options.addDisplayName(displayName);
var userAgent = new UserAgent(options, webapi);
InviterOptions.createVideoCall();
new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(target != null) {
userAgent.makeCall(target, InviterOptions.createVideoCall()).thenAccept(session -> {
//session.state
handleSession(webapi, session, container);
});
}
}).start();
userAgent.setOnInvite(invitation -> {
invitation.accept(InvitationAcceptOptions.createVideoCall());
handleSession(webapi, invitation, container);
});

return container;
}

public void handleSession(WebAPI webapi, Session session, Pane container) {
System.out.println("Session: " + session);

// Session state

var state = new Label();
state.getStyleClass().add("session-state");
state.textProperty().bind(session.stateProperty());
container.getChildren().add(state);

// When state is "established"
session.stateProperty().addListener((observable, oldValue, newValue) -> {
if (newValue.equals(Session.State.Established)) {
System.out.println("Session established");
addVideo(webapi, session, container);
}
});
}

public void addVideo(WebAPI webapi, Session session, Pane container) {
// Add local video
var localVideoStream = session.getLocalStream();
webapi.executeScript("console.log('localVideoStream: ' + "+localVideoStream.getName()+");");
var videoElement = new VideoFrame(webapi);
videoElement.getStyleClass().add("video-local");
videoElement.setStream(localVideoStream);
var description = new Label("Local Video");
container.getChildren().add(description);
container.getChildren().add(videoElement);

// Add remote video
var remoteVideoStream = session.getRemoteStream();
webapi.executeScript("console.log('remoteVideoStream: ' + "+remoteVideoStream.getName()+");");
var remoteVideoElement = new VideoFrame(webapi);
remoteVideoElement.getStyleClass().add("video-remote");
remoteVideoElement.setStream(remoteVideoStream);
var remoteDescription = new Label("Remote Video");
container.getChildren().add(remoteDescription);
container.getChildren().add(remoteVideoElement);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package one.jpro.platform.sipjs.example.page;

import com.jpro.webapi.WebAPI;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import one.jpro.platform.sipjs.api.UserAgent;
import one.jpro.platform.sipjs.api.options.InviterOptions;
import one.jpro.platform.sipjs.api.options.UserAgentOptions;
import one.jpro.platform.sipjs.api.session.Session;
import one.jpro.platform.webrtc.VideoFrame;

public class EchoPage extends VBox {

private String server = "wss://edge.sip.onsip.com";
private String target = "sip:[email protected]";
private String displayName = "EchoUser";


public EchoPage() {
var title = new Label("Echo");
title.getStyleClass().add("title");
getChildren().add(title);

WebAPI.getWebAPI(this, webapi -> {
setup(webapi);
});
getStyleClass().add("jpro-sipjs-example-page");
}

public void setup(WebAPI webapi) {
var options = new UserAgentOptions();
options.addServer(server);
options.addUri(target);
options.addDisplayName(displayName);
var userAgent = new UserAgent(options, webapi);
userAgent.makeCall(target, InviterOptions.createAudioCall()).thenAccept(session -> {
//session.state
handleSession(webapi, session);
});

System.out.println("Call made");
}

public void handleSession(WebAPI webapi, Session session) {
System.out.println("Session: " + session);

// Session state

var state = new Label();
state.textProperty().bind(session.stateProperty());
getChildren().add(state);

// When state is "established"
session.stateProperty().addListener((observable, oldValue, newValue) -> {
if (newValue.equals(Session.State.Established)) {
System.out.println("Session established");
addVideo(webapi, session);
}
});
}

public void addVideo(WebAPI webapi, Session session) {
// Add local video
// var localVideoStream = session.getLocalSteam();
var videoElement = new VideoFrame(webapi);
// videoElement.setStream(localVideoStream);
var description = new Label("Local Video");
getChildren().add(description);
getChildren().add(videoElement);

// Add remote video
var remoteVideoStream = session.getRemoteStream();
var remoteVideoElement = new VideoFrame(webapi);
//session.setupRemoteMedia(remoteVideoElement);
remoteVideoElement.setStream(remoteVideoStream);
var remoteDescription = new Label("Remote Video");
getChildren().add(remoteDescription);
getChildren().add(remoteVideoElement);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package one.jpro.platform.sipjs.example.page;

import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import one.jpro.platform.routing.LinkUtil;

public class SelectPage extends VBox {

public SelectPage() {
var button1 = new Button("Echo");
var button2 = new Button("Alice and Bob");
button1.getStyleClass().add("select-button");
button2.getStyleClass().add("select-button");
LinkUtil.setLink(button1, "/echo");
LinkUtil.setLink(button2, "/aliceAndBob");

var hbox = new HBox();
hbox.getStyleClass().add("select-page-hbox");
hbox.setAlignment(javafx.geometry.Pos.CENTER);
hbox.getChildren().addAll(button1, button2);

var title = new Label("Select a demo");
title.getStyleClass().add("select-page-title");

getChildren().add(title);
getChildren().add(hbox);
getStyleClass().add("jpro-sipjs-example-page");
}

}
25 changes: 25 additions & 0 deletions jpro-sipjs/example/src/main/resources/jpro/html/defaultpage
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>

<html>
<head>
<title>jpro Application: Hello JPro</title>
<meta name="description" content="JavaFX in the Browser: JPro enables JavaFX in the browser without any plugins."/>

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">

<link rel="stylesheet" type="text/css" href="/jpro/css/jpro-fullscreen.css">

<link rel="stylesheet" type="text/css" href="/jpro/css/jpro.css">

<script src="/jpro/js/jpro.js" type="text/javascript"></script>

</head>

<body>

<jpro-app href="/app/default" printJSCommands="true" fullscreen="true"></jpro-app>

</body>

</html>

Loading

0 comments on commit f85d8e3

Please sign in to comment.